93 lines
2.2 KiB
Rust
93 lines
2.2 KiB
Rust
use std::cmp::max;
|
|
|
|
use crate::func::*;
|
|
use crate::rcore::*;
|
|
use crate::rstd::typeless::*;
|
|
|
|
use super::*;
|
|
|
|
pub struct TestContextCounted;
|
|
|
|
impl Context for TestContextCounted {
|
|
type T = CountedClass;
|
|
|
|
type Fallible = classes::result::ResultFailOver<Self::T>;
|
|
|
|
type D = NoDiagnostic;
|
|
|
|
type LookupError<'a> = TestLookupError<'a>;
|
|
|
|
fn hash(s: &[u8]) -> Hash {
|
|
TestContextPlain::hash(s)
|
|
}
|
|
}
|
|
|
|
pub type CountedClass = classes::effect::EffectClass<usize>;
|
|
|
|
impl classes::effect::Effect for usize {
|
|
fn e_pure() -> Self {
|
|
0
|
|
}
|
|
|
|
fn e_seq(lhs: Self, rhs: Self) -> Self {
|
|
max(lhs, rhs)
|
|
}
|
|
|
|
fn e_after(self, effect: Self) -> Self {
|
|
self + effect
|
|
}
|
|
}
|
|
|
|
pub type Counted<A> = classes::effect::WithEffect<A, usize>;
|
|
|
|
impl<A> Counted<A> {
|
|
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<dyn Resolver<'a, TestContextCounted>>,
|
|
}
|
|
|
|
impl<'a> CountedResolver<'a> {
|
|
fn new(
|
|
resolver: Rc<dyn Resolver<'a, TestContextCounted>>,
|
|
) -> Rc<dyn Resolver<'a, TestContextCounted>> {
|
|
Rc::new(Self { resolver })
|
|
}
|
|
}
|
|
|
|
impl<'a> Resolver<'a, TestContextCounted> for CountedResolver<'a> {
|
|
fn resolve(self: Rc<Self>, address: Address) -> HashResolution<'a, TestContextCounted> {
|
|
CountedClass::fmap(
|
|
|resolved| {
|
|
let (src, resolver) = resolved?;
|
|
let delayed: Rc<dyn Resolver<'a, TestContextCounted>> =
|
|
Rc::new(CountedResolver { resolver });
|
|
Ok((src, delayed))
|
|
},
|
|
self.resolver.clone().resolve(address),
|
|
)
|
|
.add(1)
|
|
}
|
|
}
|
|
|
|
pub trait Delayable<'a>: Mentionable<'a, TestContextCounted> + Sized {
|
|
fn delay(self: Rc<Self>) -> CastResult<'a, TestContextCounted, Self>;
|
|
}
|
|
|
|
impl<'a, A: Mentionable<'a, TestContextCounted>> Delayable<'a> for A {
|
|
fn delay(self: Rc<Self>) -> CastResult<'a, TestContextCounted, Self> {
|
|
let factory = self.factory();
|
|
TypelessMentionable::from_typed(self).cast_full(factory, CountedResolver::new)
|
|
}
|
|
}
|