dope_sys/io/socket/route/
selector.rs1use std::num;
2
3use o3::buffer::bytes::scope;
4
5#[derive(Clone, Copy, Debug, Eq, PartialEq)]
6#[repr(transparent)]
7pub struct Offset(u8);
8
9#[derive(Clone, Copy, Debug, Eq, PartialEq)]
10#[repr(transparent)]
11pub struct Mask(num::NonZero<u8>);
12
13#[derive(Clone, Copy, Debug, Eq, PartialEq)]
15#[repr(transparent)]
16pub struct Minimum(num::NonZero<u8>);
17
18#[derive(Clone, Copy, Debug, Eq, PartialEq)]
20#[repr(transparent)]
21pub struct Length(u8);
22
23#[derive(Clone, Copy, Debug, Eq, PartialEq)]
25pub struct Selector {
26 branch_at: Offset,
27 branch_mask: Mask,
28 clear_key: Offset,
29 clear_min: Minimum,
30 length_at: Offset,
31 length: Length,
32 set_key: Offset,
33 set_min: Minimum,
34}
35
36#[derive(Clone, Copy, Debug, Eq, PartialEq)]
38pub struct PrefixPlan {
39 extent: Minimum,
40 raw_mask: Mask,
41 tags: [u8; 2],
42}
43
44#[derive(Debug)]
46pub enum Frame<'a, 'id> {
47 Direct,
48 Prefixed {
49 prefix: &'a [u8],
50 remaining: scope::Range<'id>,
51 },
52}
53
54#[derive(Clone, Copy, Debug, Eq, PartialEq)]
55pub enum PrefixError {
56 Truncated {
57 actual: usize,
58 required: num::NonZero<usize>,
59 },
60 Unknown(u8),
61 Nested(u8),
62 Inner(u8),
63}
64
65impl Offset {
66 const fn new(offset: u8) -> Self {
67 Self(offset)
68 }
69
70 pub const fn get(self) -> u8 {
71 self.0
72 }
73}
74
75impl Mask {
76 const fn new<const MASK: u8>() -> Self {
77 const {
78 assert!(MASK > 0);
79 }
80 Self(num::NonZero::<u8>::MIN.saturating_add(MASK - 1))
81 }
82
83 pub const fn get(self) -> num::NonZero<u8> {
84 self.0
85 }
86}
87
88impl Minimum {
89 const fn new<const BYTES: u8>() -> Self {
90 const {
91 assert!(BYTES > 0);
92 }
93 Self(num::NonZero::<u8>::MIN.saturating_add(BYTES - 1))
94 }
95
96 pub const fn get(self) -> num::NonZero<u8> {
97 self.0
98 }
99}
100
101impl Length {
102 pub(crate) const fn new(bytes: u8) -> Self {
103 Self(bytes)
104 }
105
106 pub const fn get(self) -> u8 {
107 self.0
108 }
109}
110
111impl Selector {
112 pub const fn fixed<
113 const BRANCH_AT: u8,
114 const BRANCH_MASK: u8,
115 const CLEAR_KEY: u8,
116 const CLEAR_MIN: u8,
117 const LENGTH_AT: u8,
118 const LENGTH: u8,
119 const SET_KEY: u8,
120 const SET_MIN: u8,
121 >() -> Self {
122 const {
123 assert!(BRANCH_AT < CLEAR_MIN);
124 assert!(CLEAR_KEY < CLEAR_MIN);
125 assert!(BRANCH_AT < SET_MIN);
126 assert!(LENGTH_AT < SET_MIN);
127 assert!(SET_KEY < SET_MIN);
128 assert!(CLEAR_MIN <= SET_MIN);
129 }
130 Self {
131 branch_at: Offset::new(BRANCH_AT),
132 branch_mask: Mask::new::<BRANCH_MASK>(),
133 clear_key: Offset::new(CLEAR_KEY),
134 clear_min: Minimum::new::<CLEAR_MIN>(),
135 length_at: Offset::new(LENGTH_AT),
136 length: Length::new(LENGTH),
137 set_key: Offset::new(SET_KEY),
138 set_min: Minimum::new::<SET_MIN>(),
139 }
140 }
141
142 pub const fn branch_at(self) -> Offset {
143 self.branch_at
144 }
145
146 pub const fn branch_mask(self) -> Mask {
147 self.branch_mask
148 }
149
150 pub const fn clear_key(self) -> Offset {
151 self.clear_key
152 }
153
154 pub const fn clear_min(self) -> Minimum {
155 self.clear_min
156 }
157
158 pub const fn length_at(self) -> Offset {
159 self.length_at
160 }
161
162 pub const fn length(self) -> Length {
163 self.length
164 }
165
166 pub const fn set_key(self) -> Offset {
167 self.set_key
168 }
169
170 pub const fn set_min(self) -> Minimum {
171 self.set_min
172 }
173}
174
175impl PrefixPlan {
176 pub const fn fixed<const BYTES: u8, const RAW_MASK: u8, const FIRST: u8, const SECOND: u8>()
177 -> Self {
178 const {
179 assert!(FIRST != SECOND);
180 assert!(FIRST & RAW_MASK == 0);
181 assert!(SECOND & RAW_MASK == 0);
182 }
183 Self {
184 extent: Minimum::new::<BYTES>(),
185 raw_mask: Mask::new::<RAW_MASK>(),
186 tags: [FIRST, SECOND],
187 }
188 }
189
190 pub const fn extent(self) -> num::NonZero<u8> {
191 self.extent.get()
192 }
193
194 pub const fn raw_mask(self) -> Mask {
195 self.raw_mask
196 }
197
198 pub const fn tags(self) -> [u8; 2] {
199 self.tags
200 }
201
202 pub fn try_parse<'a, 'id>(
203 self,
204 source: scope::View<'a, 'id>,
205 ) -> Result<Frame<'a, 'id>, PrefixError> {
206 let packet = source.as_slice();
207 let first = *packet.first().ok_or(PrefixError::Truncated {
208 actual: 0,
209 required: num::NonZero::<usize>::MIN,
210 })?;
211 let raw_mask = self.raw_mask.get().get();
212 if first & raw_mask != 0 {
213 return Ok(Frame::Direct);
214 }
215 if !self.tags.contains(&first) {
216 return Err(PrefixError::Unknown(first));
217 }
218 let truncated = PrefixError::Truncated {
219 actual: packet.len(),
220 required: num::NonZero::<usize>::from(self.extent()).saturating_add(1),
221 };
222 let (prefix, packet, remaining) = source
223 .try_split_at(self.extent().into())
224 .map_err(|_| truncated)?;
225 let first = *packet.first().ok_or(truncated)?;
226 if self.tags.contains(&first) {
227 return Err(PrefixError::Nested(first));
228 }
229 if first & raw_mask == 0 {
230 return Err(PrefixError::Inner(first));
231 }
232 Ok(Frame::Prefixed { prefix, remaining })
233 }
234}
235
236const _: () = {
237 assert!(std::mem::size_of::<Selector>() == 8);
238 assert!(std::mem::align_of::<Selector>() == 1);
239 assert!(std::mem::size_of::<PrefixPlan>() == 4);
240 assert!(std::mem::align_of::<PrefixPlan>() == 1);
241};