ipnetwork/
size.rs
1use std::{
2 cmp::Ordering,
3 fmt::Display,
4 hash::{Hash, Hasher},
5};
6
7use crate::error::NetworkSizeError;
8use NetworkSize::*;
9
10#[derive(Debug, Clone, Copy)]
27pub enum NetworkSize {
28 V4(u32),
29 V6(u128),
30}
31
32impl NetworkSize {
33 fn as_u128(&self) -> u128 {
35 match *self {
36 V4(a) => a as u128,
37 V6(a) => a,
38 }
39 }
40}
41
42impl From<u32> for NetworkSize {
43 fn from(value: u32) -> Self {
44 V4(value)
45 }
46}
47
48impl From<u128> for NetworkSize {
49 fn from(value: u128) -> Self {
50 V6(value)
51 }
52}
53
54impl TryFrom<NetworkSize> for u32 {
55 type Error = NetworkSizeError;
56 fn try_from(value: NetworkSize) -> Result<Self, Self::Error> {
57 match value {
58 V4(a) => Ok(a),
59 V6(_) => Err(NetworkSizeError::NetworkIsTooLarge),
60 }
61 }
62}
63
64impl From<NetworkSize> for u128 {
65 fn from(val: NetworkSize) -> Self {
66 val.as_u128()
67 }
68}
69
70impl PartialEq for NetworkSize {
71 fn eq(&self, other: &Self) -> bool {
72 let a = self.as_u128();
73 let b = other.as_u128();
74 a == b
75 }
76}
77
78impl Eq for NetworkSize {}
79
80impl Hash for NetworkSize {
81 fn hash<H: Hasher>(&self, state: &mut H) {
82 let a = self.as_u128();
83 a.hash(state);
84 }
85}
86
87impl Ord for NetworkSize {
88 fn cmp(&self, other: &Self) -> Ordering {
89 let a = self.as_u128();
90 let b = other.as_u128();
91 a.cmp(&b)
92 }
93}
94
95impl PartialOrd for NetworkSize {
96 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
97 Some(self.cmp(other))
98 }
99}
100
101impl Display for NetworkSize {
102 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
103 write!(f, "{}", self.as_u128())
104 }
105}
106
107#[cfg(test)]
108mod tests {
109 use super::*;
110
111 #[test]
112 fn test_from_u128() {
113 let value: u128 = 100;
114 let ns = NetworkSize::from(value);
115 assert_eq!(ns, V6(100));
116 }
117
118 #[test]
119 fn test_from_u32() {
120 let value: u32 = 100;
121 let ns = NetworkSize::from(value);
122 assert_eq!(ns, V4(100));
123 }
124
125 #[test]
126 fn test_try_into_u32() {
127 let value: u32 = 100;
128 let ns = V4(value);
129 let result: Result<u32, _> = ns.try_into();
130 assert!(result.is_ok());
131 assert_eq!(result.unwrap(), value);
132 }
133
134 #[test]
135 fn test_try_into_u32_error() {
136 let value: u128 = u32::MAX as u128 + 1;
137 let ns = V6(value);
138 let result: Result<u32, _> = ns.try_into();
139 assert!(result.is_err());
140 }
141
142 #[test]
143 fn test_into_u128() {
144 let value: u32 = 100;
145 let ns = V4(value);
146 let result: u128 = ns.into();
147 assert_eq!(result, value as u128);
148 }
149
150 #[test]
151 fn test_eq() {
152 let ns1 = V4(100);
153 let ns2 = V4(100);
154 assert_eq!(ns1, ns2);
155
156 let ns1 = V6(100);
157 let ns2 = V6(100);
158 assert_eq!(ns1, ns2);
159
160 let ns1 = V4(100);
161 let ns2 = V6(100);
162 assert_eq!(ns1, ns2);
163 }
164
165 #[test]
166 fn test_cmp() {
167 let ns1 = V4(100);
168 let ns2 = V4(200);
169 assert!(ns1 < ns2);
170
171 let ns1 = V6(200);
172 let ns2 = V6(100);
173 assert!(ns1 > ns2);
174
175 let ns1 = V4(100);
176 let ns2 = V6(200);
177 assert!(ns1 < ns2);
178 }
179
180 #[test]
181 fn test_display() {
182 let ns1 = V4(u32::MAX);
183 let ns2 = V6(ns1.into());
184 assert_eq!(ns1.to_string(), ns2.to_string());
185 }
186
187 #[test]
189 fn test_hash() {
190 let a = NetworkSize::V4(100);
191 let b = NetworkSize::V6(100);
192
193 let mut hasher = std::hash::DefaultHasher::default();
195 a.hash(&mut hasher);
196 let hash_a = hasher.finish();
197
198 let mut hasher = std::hash::DefaultHasher::default();
199 b.hash(&mut hasher);
200 let hash_b = hasher.finish();
201
202 assert_eq!(a, b);
204 assert_eq!(hash_a, hash_b);
206 }
207}