1use core::num::{NonZeroIsize, NonZeroUsize};
8
9#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash, Ord, PartialOrd)]
15pub struct PositiveIsize(isize);
16
17impl PositiveIsize {
18 pub const fn new(value: isize) -> Option<Self> {
22 if value > 0 {
23 Some(Self(value))
24 } else {
25 None
26 }
27 }
28
29 pub const fn new_unsigned(value: usize) -> Option<Self> {
33 if value == 0 || value > (isize::MAX as usize) {
34 None
35 } else {
36 Some(Self(value as isize))
37 }
38 }
39
40 pub const fn get(self) -> isize {
42 let Self(v) = self;
43 v
44 }
45}
46
47impl From<PositiveIsize> for isize {
48 fn from(PositiveIsize(value): PositiveIsize) -> Self {
49 value
50 }
51}
52
53impl From<PositiveIsize> for usize {
54 fn from(PositiveIsize(value): PositiveIsize) -> Self {
55 value as usize
58 }
59}
60
61impl From<PositiveIsize> for NonZeroIsize {
62 fn from(PositiveIsize(value): PositiveIsize) -> Self {
63 unsafe { NonZeroIsize::new_unchecked(value) }
65 }
66}
67
68impl From<PositiveIsize> for NonZeroUsize {
69 fn from(PositiveIsize(value): PositiveIsize) -> Self {
70 let value = value as usize;
72 unsafe { NonZeroUsize::new_unchecked(value) }
74 }
75}
76
77#[cfg(test)]
78mod tests {
79 use super::*;
80
81 #[test]
82 fn new_positive_isize() {
83 assert_eq!(PositiveIsize::new(0), None);
84 assert_eq!(PositiveIsize::new(-1), None);
85 assert_eq!(PositiveIsize::new(1), Some(PositiveIsize(1)));
86 assert_eq!(PositiveIsize::new(isize::MIN), None);
87 assert_eq!(PositiveIsize::new(isize::MAX), Some(PositiveIsize(isize::MAX)));
88 }
89
90 #[test]
91 fn new_unsigned_positive_isize() {
92 assert_eq!(PositiveIsize::new_unsigned(0), None);
93 assert_eq!(PositiveIsize::new_unsigned(usize::MAX), None);
94 assert_eq!(PositiveIsize::new_unsigned(1), Some(PositiveIsize(1)));
95 let max = usize::try_from(isize::MAX).unwrap();
96 assert_eq!(PositiveIsize::new_unsigned(max), Some(PositiveIsize(isize::MAX)));
97 assert_eq!(PositiveIsize::new_unsigned(max + 1), None);
98 }
99}