1use std::error::Error;
6use std::fmt;
7use std::num::NonZeroU32;
8
9use crate::LAYER_LIMIT;
10
11#[derive(Debug, Eq, PartialEq)]
12pub enum OrderError {
13 ExceededLayerLimit,
14}
15
16impl fmt::Display for OrderError {
17 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
18 write!(f, "exceeded layer limit ({})", LAYER_LIMIT)
19 }
20}
21
22impl Error for OrderError {}
23
24#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
25pub struct Order(NonZeroU32);
26
27impl Default for Order {
28 fn default() -> Self {
29 match Self::new(0) {
30 Ok(order) => order,
31 Err(_) => panic!("0 is smaller than Order::MAX"),
32 }
33 }
34}
35
36impl Order {
37 pub const MAX: Self = Self(match NonZeroU32::new(LAYER_LIMIT as u32 ^ u32::MAX) {
38 Some(val) => val,
39 None => panic!("LAYER_LIMIT is smaller than u32::MAX"),
40 });
41
42 pub const fn as_u32(&self) -> u32 {
43 self.0.get() ^ u32::MAX
44 }
45
46 pub const fn new(order: u32) -> Result<Self, OrderError> {
47 if order > Self::MAX.as_u32() {
48 Err(OrderError::ExceededLayerLimit)
49 } else {
50 Ok(Self(match NonZeroU32::new(order ^ u32::MAX) {
51 Some(val) => val,
52 None => panic!("Order::MAX is smaller than u32::MAX"),
53 }))
54 }
55 }
56}
57
58impl fmt::Debug for Order {
59 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60 f.debug_tuple("Order").field(&self.as_u32()).finish()
61 }
62}
63
64impl From<Order> for u32 {
65 fn from(order: Order) -> Self {
66 order.as_u32()
67 }
68}
69
70impl TryFrom<u32> for Order {
71 type Error = OrderError;
72
73 fn try_from(order: u32) -> Result<Self, OrderError> {
74 Self::new(order)
75 }
76}
77
78impl TryFrom<usize> for Order {
79 type Error = OrderError;
80
81 fn try_from(order: usize) -> Result<Self, OrderError> {
82 u32::try_from(order).map_err(|_| OrderError::ExceededLayerLimit).and_then(Self::try_from)
83 }
84}
85
86#[cfg(test)]
87mod tests {
88 use super::*;
89
90 #[test]
91 fn wrong_u32_order_value() {
92 let order = Order::MAX.as_u32() + 1;
93
94 assert_eq!(Order::try_from(order), Err(OrderError::ExceededLayerLimit));
95 }
96
97 #[test]
98 fn wrong_usize_order_values() {
99 let order = (Order::MAX.as_u32() + 1) as usize;
100
101 assert_eq!(Order::try_from(order), Err(OrderError::ExceededLayerLimit));
102
103 let order = u64::MAX as usize;
104
105 assert_eq!(Order::try_from(order), Err(OrderError::ExceededLayerLimit));
106 }
107
108 #[test]
109 fn correct_order_value() {
110 let order_value = Order::MAX.as_u32();
111 let order = Order::try_from(order_value);
112
113 assert_eq!(order, Ok(Order(NonZeroU32::new(order_value as u32 ^ u32::MAX).unwrap())));
114 }
115}