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