Skip to main content

dope_sys/io/socket/route/
count.rs

1use std::{mem, num};
2
3const LIMIT: u16 = u8::MAX as u16 + 1;
4
5/// A nonempty dense byte-routing domain.
6#[derive(Clone, Copy, Debug, Eq, PartialEq)]
7#[repr(transparent)]
8pub struct Count(num::NonZero<u16>);
9
10/// A dense routing index issued by an admitted datagram count.
11#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
12#[repr(transparent)]
13pub struct Index(u8);
14
15/// The rejected raw routing-domain width.
16#[derive(Clone, Copy, Debug, Eq, PartialEq)]
17#[repr(transparent)]
18pub struct Error {
19    actual: u16,
20}
21
22impl Error {
23    pub const fn actual(self) -> u16 {
24        self.actual
25    }
26}
27
28impl Count {
29    pub const MIN: Self = Self(num::NonZero::<u16>::MIN);
30    /// Converts an external route byte into an index admitted by this domain.
31    pub const fn index(self, raw: u8) -> Option<Index> {
32        if (raw as u16) < self.encode() {
33            Some(Index(raw))
34        } else {
35            None
36        }
37    }
38
39    pub const fn encode(self) -> u16 {
40        self.0.get()
41    }
42
43    /// Iterates every index proved to belong to this dense domain.
44    pub fn indices(self) -> impl ExactSizeIterator<Item = Index> + DoubleEndedIterator {
45        (0..=u8::MAX).map(Index).take(usize::from(self.encode()))
46    }
47}
48
49impl Index {
50    /// Returns the dense routing index at an indexing leaf.
51    pub const fn into_raw(self) -> usize {
52        self.0 as usize
53    }
54}
55
56impl TryFrom<u16> for Count {
57    type Error = Error;
58
59    fn try_from(value: u16) -> Result<Self, Self::Error> {
60        if value > LIMIT {
61            return Err(Error { actual: value });
62        }
63        match num::NonZero::<u16>::new(value) {
64            Some(value) => Ok(Self(value)),
65            None => Err(Error { actual: value }),
66        }
67    }
68}
69
70const _: () = assert!(mem::size_of::<Result<Count, Error>>() == 2 * mem::size_of::<u16>());