dope_sys/io/socket/route/
count.rs1use std::{mem, num};
2
3const LIMIT: u16 = u8::MAX as u16 + 1;
4
5#[derive(Clone, Copy, Debug, Eq, PartialEq)]
7#[repr(transparent)]
8pub struct Count(num::NonZero<u16>);
9
10#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
12#[repr(transparent)]
13pub struct Index(u8);
14
15#[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 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 pub fn indices(self) -> impl ExactSizeIterator<Item = Index> + DoubleEndedIterator {
45 (0..self.encode()).map(|index| Index(index as u8))
47 }
48}
49
50impl Index {
51 pub const ZERO: Self = Self(0);
52
53 pub const fn into_raw(self) -> usize {
55 self.0 as usize
56 }
57}
58
59impl TryFrom<u16> for Count {
60 type Error = Error;
61
62 fn try_from(value: u16) -> Result<Self, Self::Error> {
63 if value > LIMIT {
64 return Err(Error { actual: value });
65 }
66 match num::NonZero::<u16>::new(value) {
67 Some(value) => Ok(Self(value)),
68 None => Err(Error { actual: value }),
69 }
70 }
71}
72
73const _: () = assert!(mem::size_of::<Result<Count, Error>>() == 2 * mem::size_of::<u16>());