zenoh_keyexpr/key_expr/intersect/
mod.rs1use super::keyexpr;
16use crate::DELIMITER;
17
18mod classical;
19pub use classical::ClassicIntersector;
20pub const DEFAULT_INTERSECTOR: ClassicIntersector = ClassicIntersector;
31
32pub trait Intersector<Left, Right> {
37 fn intersect(&self, left: Left, right: Right) -> bool;
38}
39
40pub(crate) mod restriction {
41 use core::ops::Deref;
42
43 #[repr(transparent)]
44 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
45 pub struct NoBigWilds<T>(pub T);
46 #[repr(transparent)]
47 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
48 pub struct NoSubWilds<T>(pub T);
49
50 impl<T> Deref for NoBigWilds<T> {
51 type Target = T;
52
53 fn deref(&self) -> &Self::Target {
54 &self.0
55 }
56 }
57}
58#[repr(u8)]
59enum MatchComplexity {
60 NoWilds = 0,
61 ChunkWildsOnly = 1,
62 Dsl = 2,
63}
64trait KeyExprHelpers {
65 fn match_complexity(&self) -> MatchComplexity;
66}
67impl KeyExprHelpers for keyexpr {
68 fn match_complexity(&self) -> MatchComplexity {
69 let mut has_wilds = false;
70 for &c in self.as_bytes() {
71 match c {
72 b'*' => has_wilds = true,
73 b'$' => return MatchComplexity::Dsl,
74 _ => {}
75 }
76 }
77 if has_wilds {
78 MatchComplexity::ChunkWildsOnly
79 } else {
80 MatchComplexity::NoWilds
81 }
82 }
83}
84
85use restriction::NoSubWilds;
86impl<
87 T: for<'a> Intersector<&'a [u8], &'a [u8]>
88 + for<'a> Intersector<NoSubWilds<&'a [u8]>, NoSubWilds<&'a [u8]>>,
89 > Intersector<&keyexpr, &keyexpr> for T
90{
91 fn intersect(&self, left: &keyexpr, right: &keyexpr) -> bool {
92 let left_bytes = left.as_bytes();
93 let right_bytes = right.as_bytes();
94 if left_bytes == right_bytes {
95 return true;
96 }
97 match left.match_complexity() as u8 | right.match_complexity() as u8 {
98 0 => false,
99 1 => self.intersect(NoSubWilds(left_bytes), NoSubWilds(right_bytes)),
100 _ => self.intersect(left_bytes, right_bytes),
101 }
102 }
103}
104
105pub(crate) trait MayHaveVerbatim {
106 fn has_verbatim(&self) -> bool;
107 fn has_direct_verbatim(&self) -> bool;
108 unsafe fn has_direct_verbatim_non_empty(&self) -> bool {
109 self.has_direct_verbatim()
110 }
111}
112
113impl MayHaveVerbatim for [u8] {
114 fn has_direct_verbatim(&self) -> bool {
115 matches!(self, [b'@', ..])
116 }
117 fn has_verbatim(&self) -> bool {
118 self.split(|c| *c == DELIMITER)
119 .any(MayHaveVerbatim::has_direct_verbatim)
120 }
121 unsafe fn has_direct_verbatim_non_empty(&self) -> bool {
122 unsafe { *self.get_unchecked(0) == b'@' }
123 }
124}