Skip to main content

dope_sys/io/socket/route/
selector.rs

1use 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/// Minimum packet payload extent required by one selector branch.
14#[derive(Clone, Copy, Debug, Eq, PartialEq)]
15#[repr(transparent)]
16pub struct Minimum(num::NonZero<u8>);
17
18/// Packet byte interpreted as the selected shape's declared length.
19#[derive(Clone, Copy, Debug, Eq, PartialEq)]
20#[repr(transparent)]
21pub struct Length(u8);
22
23/// Selects one dense route byte from either of two packet shapes.
24#[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/// An optional fixed prefix whose tags cannot be mistaken for a direct packet.
37#[derive(Clone, Copy, Debug, Eq, PartialEq)]
38pub struct PrefixPlan {
39    extent: Minimum,
40    raw_mask: Mask,
41    tags: [u8; 2],
42}
43
44/// A borrowed prefix and the remaining range bound to its original datagram.
45#[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};