use core::num::NonZeroU16;
mod sealed {
pub trait Sealed {}
}
pub trait Dim: sealed::Sealed {
fn to_nonzero(self) -> Option<NonZeroU16>;
}
impl sealed::Sealed for i16 {}
impl Dim for i16 {
fn to_nonzero(self) -> Option<NonZeroU16> {
u16::try_from(self).ok().and_then(NonZeroU16::new)
}
}
impl sealed::Sealed for u16 {}
impl Dim for u16 {
fn to_nonzero(self) -> Option<NonZeroU16> {
NonZeroU16::new(self)
}
}
impl sealed::Sealed for i32 {}
impl Dim for i32 {
fn to_nonzero(self) -> Option<NonZeroU16> {
u16::try_from(self).ok().and_then(NonZeroU16::new)
}
}
impl sealed::Sealed for u32 {}
impl Dim for u32 {
fn to_nonzero(self) -> Option<NonZeroU16> {
u16::try_from(self).ok().and_then(NonZeroU16::new)
}
}
impl sealed::Sealed for NonZeroU16 {}
impl Dim for NonZeroU16 {
fn to_nonzero(self) -> Option<NonZeroU16> {
Some(self)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ZeroSize;
#[cfg(test)]
mod tests {
use super::*;
use core::num::NonZeroU16;
#[test]
fn i16_conversions() {
assert_eq!(5i16.to_nonzero(), NonZeroU16::new(5));
assert_eq!(0i16.to_nonzero(), None);
assert_eq!((-3i16).to_nonzero(), None);
}
#[test]
fn u16_conversions() {
assert_eq!(5u16.to_nonzero(), NonZeroU16::new(5));
assert_eq!(0u16.to_nonzero(), None);
}
#[test]
fn i32_conversions() {
assert_eq!(5i32.to_nonzero(), NonZeroU16::new(5));
assert_eq!(0i32.to_nonzero(), None);
assert_eq!((-3i32).to_nonzero(), None);
assert_eq!(70000i32.to_nonzero(), None);
}
#[test]
fn nonzero_passes_through() {
let n = NonZeroU16::new(7).unwrap();
assert_eq!(n.to_nonzero(), Some(n));
}
}