use super::OwnedKeyExpr;
fn random_chunk(rng: &'_ mut impl rand::Rng) -> impl Iterator<Item = u8> + '_ {
let n = rng.gen_range(1..3);
(0..n).map(move |_| rng.sample(rand::distributions::Uniform::from(b'a'..b'c')))
}
fn make(ke: &mut Vec<u8>, rng: &mut impl rand::Rng) {
let mut iters = 0;
loop {
let n = rng.sample(rand::distributions::Uniform::<u8>::from(0..=255));
match n {
0..=15 => ke.extend(b"/**"),
16..=31 => ke.extend(b"/*"),
32..=47 => {
if !ke.is_empty() && !ke.ends_with(b"*") {
ke.extend(b"$*")
} else {
continue;
}
}
48.. => {
if n >= 128 || ke.ends_with(b"**") || ke.ends_with(b"/*") {
ke.push(b'/')
}
ke.extend(random_chunk(rng))
}
}
if n % (10 - iters) == 0 {
return;
}
iters += 1;
}
}
pub struct KeyExprFuzzer<Rng: rand::Rng>(pub Rng);
impl<Rng: rand::Rng> Iterator for KeyExprFuzzer<Rng> {
type Item = OwnedKeyExpr;
fn next(&mut self) -> Option<Self::Item> {
let mut next = Vec::new();
make(&mut next, &mut self.0);
let mut next = String::from_utf8(next).unwrap();
if let Some(n) = next.strip_prefix('/') {
next = n.to_owned()
}
Some(OwnedKeyExpr::autocanonize(next).unwrap())
}
}