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