Skip to main content

dope_sys/io/socket/route/
selector.rs

1use std::num;
2
3use o3::buffer::bytes::scope;
4
5/// Selects one dense route byte from either of two packet shapes.
6#[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/// An optional fixed prefix whose tags cannot be mistaken for a direct packet.
19#[derive(Clone, Copy, Debug, Eq, PartialEq)]
20pub struct PrefixPlan {
21    extent: num::NonZero<u8>,
22    raw_mask: num::NonZero<u8>,
23    tags: [u8; 2],
24}
25
26/// A borrowed prefix and the remaining range bound to its original datagram.
27#[derive(Debug)]
28pub enum Frame<'a, 'id> {
29    Direct,
30    Prefixed {
31        prefix: &'a [u8],
32        remaining: scope::Range<'id>,
33    },
34}
35
36#[derive(Clone, Copy, Debug, Eq, PartialEq)]
37pub enum PrefixError {
38    Truncated {
39        actual: usize,
40        required: num::NonZero<usize>,
41    },
42    Unknown(u8),
43    Nested(u8),
44    Inner(u8),
45}
46
47impl Selector {
48    pub const fn fixed<
49        const BRANCH_AT: u8,
50        const BRANCH_MASK: u8,
51        const CLEAR_KEY: u8,
52        const CLEAR_MIN: u8,
53        const LENGTH_AT: u8,
54        const LENGTH: u8,
55        const SET_KEY: u8,
56        const SET_MIN: u8,
57    >() -> Self {
58        const {
59            assert!(BRANCH_MASK > 0);
60            assert!(BRANCH_AT < CLEAR_MIN);
61            assert!(CLEAR_KEY < CLEAR_MIN);
62            assert!(BRANCH_AT < SET_MIN);
63            assert!(LENGTH_AT < SET_MIN);
64            assert!(SET_KEY < SET_MIN);
65            assert!(CLEAR_MIN <= SET_MIN);
66        }
67        Self {
68            branch_at: BRANCH_AT,
69            branch_mask: num::NonZero::<u8>::MIN.saturating_add(BRANCH_MASK - 1),
70            clear_key: CLEAR_KEY,
71            clear_min: num::NonZero::<u8>::MIN.saturating_add(CLEAR_MIN - 1),
72            length_at: LENGTH_AT,
73            length: LENGTH,
74            set_key: SET_KEY,
75            set_min: num::NonZero::<u8>::MIN.saturating_add(SET_MIN - 1),
76        }
77    }
78
79    pub const fn branch_at(self) -> u8 {
80        self.branch_at
81    }
82
83    pub const fn branch_mask(self) -> num::NonZero<u8> {
84        self.branch_mask
85    }
86
87    pub const fn clear_key(self) -> u8 {
88        self.clear_key
89    }
90
91    pub const fn clear_min(self) -> num::NonZero<u8> {
92        self.clear_min
93    }
94
95    pub const fn length_at(self) -> u8 {
96        self.length_at
97    }
98
99    pub const fn length(self) -> u8 {
100        self.length
101    }
102
103    pub const fn set_key(self) -> u8 {
104        self.set_key
105    }
106
107    pub const fn set_min(self) -> num::NonZero<u8> {
108        self.set_min
109    }
110}
111
112impl PrefixPlan {
113    pub const fn fixed<const BYTES: u8, const RAW_MASK: u8, const FIRST: u8, const SECOND: u8>()
114    -> Self {
115        const {
116            assert!(BYTES > 0);
117            assert!(RAW_MASK > 0);
118            assert!(FIRST != SECOND);
119            assert!(FIRST & RAW_MASK == 0);
120            assert!(SECOND & RAW_MASK == 0);
121        }
122        Self {
123            extent: num::NonZero::<u8>::MIN.saturating_add(BYTES - 1),
124            raw_mask: num::NonZero::<u8>::MIN.saturating_add(RAW_MASK - 1),
125            tags: [FIRST, SECOND],
126        }
127    }
128
129    pub const fn extent(self) -> num::NonZero<u8> {
130        self.extent
131    }
132
133    pub const fn raw_mask(self) -> num::NonZero<u8> {
134        self.raw_mask
135    }
136
137    pub const fn tags(self) -> [u8; 2] {
138        self.tags
139    }
140
141    pub fn try_parse<'a, 'id>(
142        self,
143        source: scope::View<'a, 'id>,
144    ) -> Result<Frame<'a, 'id>, PrefixError> {
145        let packet = source.as_slice();
146        let first = *packet.first().ok_or(PrefixError::Truncated {
147            actual: 0,
148            required: num::NonZero::<usize>::MIN,
149        })?;
150        let raw_mask = self.raw_mask.get();
151        if first & raw_mask != 0 {
152            return Ok(Frame::Direct);
153        }
154        if !self.tags.contains(&first) {
155            return Err(PrefixError::Unknown(first));
156        }
157        let truncated = PrefixError::Truncated {
158            actual: packet.len(),
159            required: num::NonZero::<usize>::from(self.extent()).saturating_add(1),
160        };
161        let (prefix, packet, remaining) = source
162            .try_split_at(self.extent().into())
163            .map_err(|_| truncated)?;
164        let first = *packet.first().ok_or(truncated)?;
165        if self.tags.contains(&first) {
166            return Err(PrefixError::Nested(first));
167        }
168        if first & raw_mask == 0 {
169            return Err(PrefixError::Inner(first));
170        }
171        Ok(Frame::Prefixed { prefix, remaining })
172    }
173}
174
175const _: () = {
176    assert!(std::mem::size_of::<Selector>() == 8);
177    assert!(std::mem::align_of::<Selector>() == 1);
178    assert!(std::mem::size_of::<PrefixPlan>() == 4);
179    assert!(std::mem::align_of::<PrefixPlan>() == 1);
180};