use std::fmt;
use crate::error::ValueError;
macro_rules! bounded_int {
($name:ident, $inner:ty, $min:expr, $max:expr $(,)?) => {
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct $name($inner);
impl $name {
pub const MIN: $inner = $min;
pub const MAX: $inner = $max;
pub fn new(value: $inner) -> Result<Self, ValueError> {
if ($min..=$max).contains(&value) {
Ok(Self(value))
} else {
Err(ValueError::OutOfRange {
value: value as i64,
min: $min as i64,
max: $max as i64,
})
}
}
pub const fn new_unchecked(value: $inner) -> Self {
Self(value)
}
pub fn get(&self) -> $inner {
self.0
}
}
impl fmt::Display for $name {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
};
}
bounded_int!(PollInterval, i8, -32, 32);
bounded_int!(UdpPort, u16, 0, 65535);
bounded_int!(Dscp, u8, 0, 63);
bounded_int!(Stratum, u8, 0, 15);
bounded_int!(SamplesCount, u32, 0, i32::MAX as u32);
bounded_int!(PollTarget, u32, 6, 60);
bounded_int!(NtpVersion, u8, 1, 4);
bounded_int!(PpsRate, u32, 1, i32::MAX as u32);
bounded_int!(SchedPriority, u8, 0, 100);
bounded_int!(PtpDomain, u8, 0, 255);
bounded_int!(ClientLogSize, u64, 0, 2147483648);
bounded_int!(TxBuffers, u32, 0, 1048576);
bounded_int!(NtsProcesses, u16, 0, 1000);
impl TryFrom<i32> for PollInterval {
type Error = ValueError;
fn try_from(v: i32) -> Result<Self, Self::Error> {
Self::new(v as i8)
}
}
impl TryFrom<i32> for UdpPort {
type Error = ValueError;
fn try_from(v: i32) -> Result<Self, Self::Error> {
Self::new(v as u16)
}
}
impl TryFrom<i32> for Dscp {
type Error = ValueError;
fn try_from(v: i32) -> Result<Self, Self::Error> {
Self::new(v as u8)
}
}
impl TryFrom<i32> for Stratum {
type Error = ValueError;
fn try_from(v: i32) -> Result<Self, Self::Error> {
Self::new(v as u8)
}
}
impl TryFrom<i32> for PollTarget {
type Error = ValueError;
fn try_from(v: i32) -> Result<Self, Self::Error> {
Self::new(v as u32)
}
}
impl TryFrom<i32> for NtpVersion {
type Error = ValueError;
fn try_from(v: i32) -> Result<Self, Self::Error> {
Self::new(v as u8)
}
}
impl TryFrom<i32> for PpsRate {
type Error = ValueError;
fn try_from(v: i32) -> Result<Self, Self::Error> {
Self::new(v as u32)
}
}
impl TryFrom<i32> for SchedPriority {
type Error = ValueError;
fn try_from(v: i32) -> Result<Self, Self::Error> {
Self::new(v as u8)
}
}
impl TryFrom<i32> for PtpDomain {
type Error = ValueError;
fn try_from(v: i32) -> Result<Self, Self::Error> {
Self::new(v as u8)
}
}
impl TryFrom<i32> for TxBuffers {
type Error = ValueError;
fn try_from(v: i32) -> Result<Self, Self::Error> {
Self::new(v as u32)
}
}
impl TryFrom<i32> for NtsProcesses {
type Error = ValueError;
fn try_from(v: i32) -> Result<Self, Self::Error> {
Self::new(v as u16)
}
}
impl TryFrom<i64> for ClientLogSize {
type Error = ValueError;
fn try_from(v: i64) -> Result<Self, Self::Error> {
Self::new(v as u64)
}
}
impl From<PollInterval> for i8 { fn from(v: PollInterval) -> Self { v.0 } }
impl From<UdpPort> for u16 { fn from(v: UdpPort) -> Self { v.0 } }
impl From<Dscp> for u8 { fn from(v: Dscp) -> Self { v.0 } }
impl From<Stratum> for u8 { fn from(v: Stratum) -> Self { v.0 } }
impl From<SamplesCount> for u32 { fn from(v: SamplesCount) -> Self { v.0 } }
impl From<PollTarget> for u32 { fn from(v: PollTarget) -> Self { v.0 } }
impl From<NtpVersion> for u8 { fn from(v: NtpVersion) -> Self { v.0 } }
impl From<PpsRate> for u32 { fn from(v: PpsRate) -> Self { v.0 } }
impl From<SchedPriority> for u8 { fn from(v: SchedPriority) -> Self { v.0 } }
impl From<PtpDomain> for u8 { fn from(v: PtpDomain) -> Self { v.0 } }
impl From<ClientLogSize> for u64 { fn from(v: ClientLogSize) -> Self { v.0 } }
impl From<TxBuffers> for u32 { fn from(v: TxBuffers) -> Self { v.0 } }
impl From<NtsProcesses> for u16 { fn from(v: NtsProcesses) -> Self { v.0 } }