//! Some simple helpers for recursive sampling. use crate::{Random, Sample}; use std::ops::Range; pub trait Recursion { type Output; fn recurse(&self, g: &mut Random, inner: RecursiveSampler) -> Self::Output where Self: Sized; } #[derive(Debug, Clone)] pub struct RecursiveSampler { pub depth: Option>, pub node: G, } impl RecursiveSampler { fn lower(&self) -> Self { let depth = self .depth .as_ref() .map(|d| d.start.saturating_sub(1)..d.end.saturating_sub(1)); Self { depth, ..self.clone() } } } impl Sample for RecursiveSampler where G: Recursion + Sample + Clone, N: 'static, { type Output = N; fn generate(&mut self, g: &mut Random) -> Self::Output { match &self.depth { Some(depth) => { if depth.start > 0 { self.node.recurse(g, self.lower()) } else { if depth.end > 0 { self.node.recurse(g, self.lower()) } else { self.node.generate(g) } } } None => self.node.recurse(g, self.lower()), } } }