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