88 lines
2.1 KiB
Rust
88 lines
2.1 KiB
Rust
use std::cmp::max;
|
|
|
|
use crate::func::*;
|
|
use crate::rcore::*;
|
|
use crate::rstd::typeless::*;
|
|
|
|
use super::*;
|
|
|
|
pub struct TestContextCounted;
|
|
|
|
impl<'a> Context<'a> for TestContextCounted {
|
|
type T = CountedInstance;
|
|
|
|
type Fallible = instances::result::ResultFailOver<Self::T>;
|
|
|
|
type D = NoDiagnostic;
|
|
|
|
type LookupError = TestLookupError<'a>;
|
|
|
|
fn hash(s: &[u8]) -> Hash {
|
|
TestContextPlain::hash(s)
|
|
}
|
|
}
|
|
|
|
pub type CountedInstance = instances::effect::EffectInstance<usize>;
|
|
|
|
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<A> = instances::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> {
|
|
CountedInstance::fmap(self.resolver.clone().resolve(address), |resolved| {
|
|
let (src, resolver) = resolved?;
|
|
let delayed: Rc<dyn Resolver<'a, TestContextCounted>> =
|
|
Rc::new(CountedResolver { resolver });
|
|
Ok((src, delayed))
|
|
})
|
|
.add(1)
|
|
}
|
|
}
|
|
|
|
pub trait Delayable<'a>: Mentionable<'a, TestContextCounted> + Sized {
|
|
fn delay(self: Rc<Self>) -> 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 {}
|