use std::cmp::max; use crate::func::{context::*, *}; use crate::rcore::*; use crate::rstd::typeless::*; use super::*; pub struct TestContextCounted; impl<'a> FunctorContext<'a> for TestContextCounted { type T = CountedInstance; } impl<'a> Context<'a> for TestContextCounted { type _Tm = Self::T; type Fallible = instances::result::ResultFailOver; type D = NoDiagnostic; type LookupError = TestLookupError<'a>; fn hash(s: &[u8]) -> Hash { TestContextPlain::hash(s) } } pub type CountedInstance = instances::effect::EffectInstance; impl instances::effect::Effect for usize { fn e_pure() -> Self { 0 } fn e_seq(el: Self, er: Self) -> Self { max(el, er) } fn e_after(self, effect: Self) -> Self { self + effect } } pub type Counted = instances::effect::WithEffect; impl Counted { fn add(self, n: usize) -> Self { Counted { value: self.value, effect: self.effect + n, } } pub fn count(&self) -> usize { self.effect } } struct CountedResolver<'a> { resolver: Rc>, } impl<'a> CountedResolver<'a> { fn new( resolver: Rc>, ) -> Rc> { Rc::new(Self { resolver }) } } impl<'a> Resolver<'a, TestContextCounted> for CountedResolver<'a> { fn resolve(self: Rc, address: Address) -> HashResolution<'a, TestContextCounted> { CountedInstance::fmap(self.resolver.clone().resolve(address), |resolved| { let (src, resolver) = resolved?; let delayed: Rc> = Rc::new(CountedResolver { resolver }); Ok((src, delayed)) }) .add(1) } } pub trait Delayable<'a>: Mentionable<'a, TestContextCounted> + Sized { fn delay(self: Rc) -> CastResult<'a, TestContextCounted, Self> { let factory = self.factory(); TypelessMentionable::from_typed(self).cast_full(factory, CountedResolver::new) } } impl<'a, A: Mentionable<'a, TestContextCounted>> Delayable<'a> for A {}