use {
crate::{
pbt::{
Algebraic, ArbitraryFn, CtorFn, Decomposition, ElimFn, IntroductionRule, Pbt,
TypeFormer, try_arbitrary_field, visit_self,
},
reflection::{TermsOfVariousTypes, Type, register, type_of},
scc::StronglyConnectedComponents,
},
alloc::collections::BTreeSet,
core::{iter, num::NonZero},
};
impl<T: Pbt> Pbt for Box<T> {
#[inline]
fn register_all_immediate_dependencies(
visited: &mut BTreeSet<Type>,
sccs: &mut StronglyConnectedComponents,
) {
if !visited.insert(type_of::<Self>()) {
return;
}
let () = register::<T>(visited.clone(), sccs);
}
#[inline]
fn type_former() -> TypeFormer<Self> {
TypeFormer::Algebraic(Algebraic {
introduction_rules: Box::new([IntroductionRule {
arbitrary: ArbitraryFn::new(|prng, swarm, mut sizes| {
Ok(Some(Box::new(try_arbitrary_field::<T>(
&mut sizes, prng, swarm,
)?)))
}),
call: CtorFn::new(|terms| Some(Box::new(terms.must_pop()))),
immediate_dependencies: iter::once(type_of::<T>()).collect(),
}]),
elimination_rule: ElimFn::new(|boxed| {
let mut fields = TermsOfVariousTypes::new();
let () = fields.push::<T>(*boxed);
Decomposition {
ctor_idx: const { NonZero::new(1).unwrap() },
fields,
}
}),
})
}
#[inline]
fn visit_deep<V>(&self) -> impl Iterator<Item = V>
where
V: Pbt,
{
visit_self(self).chain(self.as_ref().visit_deep())
}
}