zenoh_protocol_core/key_expr/intersect/
mod.rs1use super::keyexpr;
16
17mod classical;
18pub use classical::ClassicIntersector;
19#[deprecated = "This module hasn't been updated to support the $* DSL yet"]
20pub(crate) mod ltr;
21#[deprecated = "This module hasn't been updated to support the $* DSL yet"]
22pub(crate) mod ltr_chunk;
23#[deprecated = "This module hasn't been updated to support the $* DSL yet"]
24pub(crate) mod middle_out;
25pub const DEFAULT_INTERSECTOR: ClassicIntersector = ClassicIntersector;
30
31pub trait Intersector<Left, Right> {
36 fn intersect(&self, left: Left, right: Right) -> bool;
37}
38
39pub(crate) mod restiction {
40 #[repr(transparent)]
41 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
42 pub struct NoBigWilds<T>(pub T);
43 #[repr(transparent)]
44 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
45 pub struct NoSubWilds<T>(pub T);
46 impl<T> std::ops::Deref for NoBigWilds<T> {
47 type Target = T;
48 fn deref(&self) -> &Self::Target {
49 &self.0
50 }
51 }
52}
53#[repr(u8)]
54enum MatchComplexity {
55 NoWilds = 0,
56 ChunkWildsOnly = 1,
57 Dsl = 2,
58}
59trait KeyExprHelpers {
60 fn match_complexity(&self) -> MatchComplexity;
61}
62impl KeyExprHelpers for keyexpr {
63 fn match_complexity(&self) -> MatchComplexity {
64 let mut has_wilds = false;
65 for &c in self.as_bytes() {
66 match c {
67 b'*' => has_wilds = true,
68 b'$' => return MatchComplexity::Dsl,
69 _ => {}
70 }
71 }
72 if has_wilds {
73 MatchComplexity::ChunkWildsOnly
74 } else {
75 MatchComplexity::NoWilds
76 }
77 }
78}
79
80use restiction::NoSubWilds;
81impl<
82 T: for<'a> Intersector<&'a [u8], &'a [u8]>
83 + for<'a> Intersector<NoSubWilds<&'a [u8]>, NoSubWilds<&'a [u8]>>,
84 > Intersector<&keyexpr, &keyexpr> for T
85{
86 fn intersect(&self, left: &keyexpr, right: &keyexpr) -> bool {
87 let left_bytes = left.as_bytes();
88 let right_bytes = right.as_bytes();
89 if left_bytes == right_bytes {
90 return true;
91 }
92 match left.match_complexity() as u8 | right.match_complexity() as u8 {
93 0 => false,
94 1 => self.intersect(NoSubWilds(left_bytes), NoSubWilds(right_bytes)),
95 _ => self.intersect(left_bytes, right_bytes),
96 }
97 }
98}