1use std::fmt;
27
28use crate::error::ValueError;
29
30macro_rules! bounded_int {
31 ($name:ident, $inner:ty, $min:expr, $max:expr $(,)?) => {
32 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
36 pub struct $name($inner);
37
38 impl $name {
39 pub const MIN: $inner = $min;
41 pub const MAX: $inner = $max;
43
44 pub fn new(value: $inner) -> Result<Self, ValueError> {
59 if ($min..=$max).contains(&value) {
60 Ok(Self(value))
61 } else {
62 Err(ValueError::OutOfRange {
63 value: value as i64,
64 min: $min as i64,
65 max: $max as i64,
66 })
67 }
68 }
69
70 pub const fn new_unchecked(value: $inner) -> Self {
75 Self(value)
76 }
77
78 pub fn get(&self) -> $inner {
80 self.0
81 }
82 }
83
84 impl fmt::Display for $name {
85 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
86 write!(f, "{}", self.0)
87 }
88 }
89 };
90}
91
92bounded_int!(PollInterval, i8, -32, 32);
93bounded_int!(UdpPort, u16, 0, 65535);
94bounded_int!(Dscp, u8, 0, 63);
95bounded_int!(Stratum, u8, 0, 15);
96bounded_int!(SamplesCount, u32, 0, i32::MAX as u32);
97bounded_int!(PollTarget, u32, 6, 60);
98bounded_int!(NtpVersion, u8, 1, 4);
99bounded_int!(PpsRate, u32, 1, i32::MAX as u32);
100bounded_int!(SchedPriority, u8, 0, 100);
101bounded_int!(PtpDomain, u8, 0, 255);
102bounded_int!(ClientLogSize, u64, 0, 2147483648);
103bounded_int!(TxBuffers, u32, 0, 1048576);
104bounded_int!(NtsProcesses, u16, 0, 1000);
105
106impl TryFrom<i32> for PollInterval {
109 type Error = ValueError;
110 fn try_from(v: i32) -> Result<Self, Self::Error> {
111 Self::new(v as i8)
112 }
113}
114
115impl TryFrom<i32> for UdpPort {
116 type Error = ValueError;
117 fn try_from(v: i32) -> Result<Self, Self::Error> {
118 Self::new(v as u16)
119 }
120}
121
122impl TryFrom<i32> for Dscp {
123 type Error = ValueError;
124 fn try_from(v: i32) -> Result<Self, Self::Error> {
125 Self::new(v as u8)
126 }
127}
128
129impl TryFrom<i32> for Stratum {
130 type Error = ValueError;
131 fn try_from(v: i32) -> Result<Self, Self::Error> {
132 Self::new(v as u8)
133 }
134}
135
136impl TryFrom<i32> for PollTarget {
137 type Error = ValueError;
138 fn try_from(v: i32) -> Result<Self, Self::Error> {
139 Self::new(v as u32)
140 }
141}
142
143impl TryFrom<i32> for NtpVersion {
144 type Error = ValueError;
145 fn try_from(v: i32) -> Result<Self, Self::Error> {
146 Self::new(v as u8)
147 }
148}
149
150impl TryFrom<i32> for PpsRate {
151 type Error = ValueError;
152 fn try_from(v: i32) -> Result<Self, Self::Error> {
153 Self::new(v as u32)
154 }
155}
156
157impl TryFrom<i32> for SchedPriority {
158 type Error = ValueError;
159 fn try_from(v: i32) -> Result<Self, Self::Error> {
160 Self::new(v as u8)
161 }
162}
163
164impl TryFrom<i32> for PtpDomain {
165 type Error = ValueError;
166 fn try_from(v: i32) -> Result<Self, Self::Error> {
167 Self::new(v as u8)
168 }
169}
170
171impl TryFrom<i32> for TxBuffers {
172 type Error = ValueError;
173 fn try_from(v: i32) -> Result<Self, Self::Error> {
174 Self::new(v as u32)
175 }
176}
177
178impl TryFrom<i32> for NtsProcesses {
179 type Error = ValueError;
180 fn try_from(v: i32) -> Result<Self, Self::Error> {
181 Self::new(v as u16)
182 }
183}
184
185impl TryFrom<i64> for ClientLogSize {
186 type Error = ValueError;
187 fn try_from(v: i64) -> Result<Self, Self::Error> {
188 Self::new(v as u64)
189 }
190}
191
192impl From<PollInterval> for i8 { fn from(v: PollInterval) -> Self { v.0 } }
195impl From<UdpPort> for u16 { fn from(v: UdpPort) -> Self { v.0 } }
196impl From<Dscp> for u8 { fn from(v: Dscp) -> Self { v.0 } }
197impl From<Stratum> for u8 { fn from(v: Stratum) -> Self { v.0 } }
198impl From<SamplesCount> for u32 { fn from(v: SamplesCount) -> Self { v.0 } }
199impl From<PollTarget> for u32 { fn from(v: PollTarget) -> Self { v.0 } }
200impl From<NtpVersion> for u8 { fn from(v: NtpVersion) -> Self { v.0 } }
201impl From<PpsRate> for u32 { fn from(v: PpsRate) -> Self { v.0 } }
202impl From<SchedPriority> for u8 { fn from(v: SchedPriority) -> Self { v.0 } }
203impl From<PtpDomain> for u8 { fn from(v: PtpDomain) -> Self { v.0 } }
204impl From<ClientLogSize> for u64 { fn from(v: ClientLogSize) -> Self { v.0 } }
205impl From<TxBuffers> for u32 { fn from(v: TxBuffers) -> Self { v.0 } }
206impl From<NtsProcesses> for u16 { fn from(v: NtsProcesses) -> Self { v.0 } }
207
208