110 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			110 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| pub mod counted;
 | |
| pub mod traced;
 | |
| 
 | |
| use std::{error::Error, fmt::Display, rc::Rc};
 | |
| 
 | |
| use sha2::{Digest, Sha256};
 | |
| 
 | |
| use crate::func::{context::*, *};
 | |
| use crate::rcore::*;
 | |
| use crate::rstd::{cast::*, inject::*, typeless::*};
 | |
| 
 | |
| pub struct NoDiagnostic;
 | |
| 
 | |
| impl<'a, T: Monad<'a>> Diagnostic<'a, T> for NoDiagnostic {
 | |
|     fn after<'b, A>(fa: T::F<A>, _event: impl 'b + FnOnce() -> String) -> T::F<A> {
 | |
|         fa
 | |
|     }
 | |
| 
 | |
|     fn before<'b, A>(fa: T::F<A>, _event: impl 'b + FnOnce() -> String) -> T::F<A> {
 | |
|         fa
 | |
|     }
 | |
| 
 | |
|     fn wrapped<'b, A>(fa: T::F<A>, _event: impl 'b + FnOnce() -> String) -> T::F<A> {
 | |
|         fa
 | |
|     }
 | |
| }
 | |
| 
 | |
| pub struct TestContextPlain;
 | |
| 
 | |
| #[derive(Debug)]
 | |
| pub enum TestLookupError<'a> {
 | |
|     Typeless(TypelessError<'a>),
 | |
|     Cast(CastError<'a>),
 | |
|     EmptyResolverAccess(Address),
 | |
| }
 | |
| 
 | |
| impl<'a> From<TypelessError<'a>> for TestLookupError<'a> {
 | |
|     fn from(value: TypelessError<'a>) -> Self {
 | |
|         Self::Typeless(value)
 | |
|     }
 | |
| }
 | |
| 
 | |
| impl<'a> From<CastError<'a>> for TestLookupError<'a> {
 | |
|     fn from(value: CastError<'a>) -> Self {
 | |
|         Self::Cast(value)
 | |
|     }
 | |
| }
 | |
| 
 | |
| impl<'a> Display for TestLookupError<'a> {
 | |
|     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 | |
|         match self {
 | |
|             Self::Typeless(typeless_error) => {
 | |
|                 write!(f, "typeless lookup failure: {}", typeless_error)
 | |
|             }
 | |
|             Self::Cast(cast_error) => {
 | |
|                 write!(f, "cast failure: {}", cast_error)
 | |
|             }
 | |
|             Self::EmptyResolverAccess(address) => {
 | |
|                 write!(f, "accessed an empty resolved at address {}", address)
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| impl<'a> Error for TestLookupError<'a> {}
 | |
| 
 | |
| impl<'a> FunctorContext<'a> for TestContextPlain {
 | |
|     type T = instances::solo::SoloInstance;
 | |
| }
 | |
| 
 | |
| impl<'a> FallibleCtx<'a> for TestContextPlain {
 | |
|     type Fallible = instances::result::ResultFailAny;
 | |
| }
 | |
| 
 | |
| impl<'a> Context<'a> for TestContextPlain {
 | |
|     type _Tm = Self::T;
 | |
| 
 | |
|     type D = NoDiagnostic;
 | |
| 
 | |
|     type LookupError = TestLookupError<'a>;
 | |
| 
 | |
|     fn hash(s: &[u8]) -> Hash {
 | |
|         let mut hasher = Sha256::new();
 | |
|         hasher.update(s);
 | |
|         hasher.finalize().into()
 | |
|     }
 | |
| }
 | |
| 
 | |
| pub struct EmptyResolver;
 | |
| 
 | |
| impl<'a> Resolver<'a, TestContextPlain> for EmptyResolver {
 | |
|     fn resolve(self: std::rc::Rc<Self>, address: Address) -> HashResolution<'a, TestContextPlain> {
 | |
|         Err(TestLookupError::EmptyResolverAccess(address))
 | |
|     }
 | |
| }
 | |
| 
 | |
| struct EmptyInject;
 | |
| 
 | |
| impl<'a, Ctx: Context<'a>> Inject<'a, Ctx> for EmptyInject {
 | |
|     fn inject<A: 'a>(&self, fa: Wrapped<'a, Ctx, A>) -> Wrapped<'a, Ctx, A> {
 | |
|         fa
 | |
|     }
 | |
| }
 | |
| 
 | |
| pub fn reparse<'a, A: Mentionable<'a, TestContextPlain>>(mentionable: Rc<A>) -> A {
 | |
|     Rc::new(EmptyInject)
 | |
|         .inject_mentionable(mentionable.as_ref())
 | |
|         .expect("re-parsing failed")
 | |
| }
 |