zenoh_keyexpr/key_expr/
fuzzer.rs1use super::OwnedKeyExpr;
15
16fn random_chunk(rng: &'_ mut impl rand::Rng) -> impl Iterator<Item = u8> + '_ {
17 let n = rng.gen_range(1..3);
18 rng.gen_bool(0.05)
19 .then_some(b'@')
20 .into_iter()
21 .chain((0..n).map(move |_| rng.sample(rand::distributions::Uniform::from(b'a'..b'c'))))
22}
23
24fn make(ke: &mut Vec<u8>, rng: &mut impl rand::Rng) {
25 let mut iters = 0;
26 loop {
27 let n = rng.sample(rand::distributions::Uniform::<u8>::from(0..=255));
28 match n {
29 0..=15 => ke.extend(b"/**"),
30 16..=31 => ke.extend(b"/*"),
31 32..=47 => {
32 if !ke.is_empty() && !ke.ends_with(b"*") {
33 ke.extend(b"$*")
34 } else {
35 continue;
36 }
37 }
38 48.. => {
39 if n >= 128 || ke.ends_with(b"**") || ke.ends_with(b"/*") {
40 ke.push(b'/')
41 }
42 ke.extend(random_chunk(rng))
43 }
44 }
45 if n % (10 - iters) == 0 {
46 return;
47 }
48 iters += 1;
49 }
50}
51
52pub struct KeyExprFuzzer<Rng: rand::Rng>(pub Rng);
53impl<Rng: rand::Rng> Iterator for KeyExprFuzzer<Rng> {
54 type Item = OwnedKeyExpr;
55 fn next(&mut self) -> Option<Self::Item> {
56 let mut next = Vec::new();
57 make(&mut next, &mut self.0);
58 let mut next = String::from_utf8(next).unwrap();
59 if let Some(n) = next.strip_prefix('/').map(ToOwned::to_owned) {
60 next = n
61 }
62 Some(OwnedKeyExpr::autocanonize(next).unwrap())
63 }
64}