use crate::{data::arbitrary::ArbitrarySpecs, iter_utils::ProcessResultsExt};
use arbitrary::{Result, Unstructured};
#[derive(Clone, Eq, PartialEq, Hash, Debug)]
pub struct VecSpecs<S> {
pub element_specs: S,
pub min_len: usize,
pub len: Option<usize>,
pub max_len: usize,
}
impl<S> Default for VecSpecs<S>
where
S: Default,
{
fn default() -> Self {
Self {
element_specs: S::default(),
min_len: 0,
len: None,
max_len: usize::MAX,
}
}
}
impl<'a, S> ArbitrarySpecs<'a> for VecSpecs<S>
where
S: ArbitrarySpecs<'a>,
{
type Output = Vec<S::Output>;
#[inline]
fn make_arbitrary(&self, u: &mut Unstructured<'a>) -> Result<Self::Output> {
let vec = if let Some(len) = self.len {
std::iter::repeat_with(|| self.element_specs.make_arbitrary(u))
.take(len)
.collect::<Result<Vec<_>>>()?
} else {
let start = std::iter::repeat_with(|| self.element_specs.make_arbitrary(u)).take(self.min_len);
let mut out = start.collect::<Result<Vec<_>>>()?;
let remaining_len = self.max_len - self.min_len;
let remaining = self.element_specs.make_arbitrary_iter(u).take(remaining_len);
remaining.process_results(|iter| {
out.extend(iter);
})?;
out
};
Ok(vec)
}
}