@@ -4,28 +4,14 @@ use std::{
4
4
str:: FromStr ,
5
5
} ;
6
6
7
+ use crate :: Error ;
8
+
7
9
#[ derive( Clone , Copy , Debug , Eq , Hash , Ord , PartialEq , PartialOrd ) ]
8
10
pub struct Cidr {
9
11
network : Ipv4Addr ,
10
12
prefix : u8 ,
11
13
}
12
14
13
- #[ derive( Clone , Debug , Eq , Ord , PartialEq , PartialOrd ) ]
14
- pub enum Error {
15
- CidrNotInRange ( String ) ,
16
- InvalidNetwork ( String ) ,
17
- InvalidPrefix ( String ) ,
18
- Parse ( String ) ,
19
- TypeCast ( String ) ,
20
- Impossible ( String ) ,
21
- }
22
-
23
- impl Display for Error {
24
- fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
25
- write ! ( f, "{self:?}" )
26
- }
27
- }
28
-
29
15
impl Cidr {
30
16
pub fn new ( network : Ipv4Addr , prefix : u8 ) -> Result < Self , Error > {
31
17
if prefix as u32 > u32:: BITS {
@@ -84,22 +70,58 @@ impl Cidr {
84
70
Ipv4Addr :: from ( last)
85
71
}
86
72
87
- pub fn contains < T > ( & self , net : T ) -> Result < bool , Error >
73
+ pub fn contains < T > ( & self , net : T ) -> bool
88
74
where
89
- T : Copy + Debug + TryInto < Cidr > ,
75
+ T : Copy + Debug + Into < Cidr > ,
90
76
{
91
- let cidr: Cidr = net
92
- . try_into ( )
93
- . map_err ( |_| Error :: TypeCast ( format ! ( "could not cast value '{:?}' to cidr" , net) ) ) ?;
94
- Ok ( cidr. first ( ) >= self . first ( ) && cidr. last ( ) <= self . last ( ) )
77
+ let cidr: Cidr = net. into ( ) ;
78
+ cidr. first ( ) >= self . first ( ) && cidr. last ( ) <= self . last ( )
79
+ }
80
+
81
+ pub fn parent ( & self ) -> Option < Cidr > {
82
+ match self . prefix {
83
+ 0 => None ,
84
+ 1 => Some ( Self :: default ( ) ) ,
85
+ _ => {
86
+ let prefix = self . prefix - 1 ;
87
+ let shift = u32:: BITS - prefix as u32 ;
88
+ Some ( Self {
89
+ network : ( u32:: from ( self . network ) >> shift << shift) . into ( ) ,
90
+ prefix,
91
+ } )
92
+ }
93
+ }
95
94
}
96
95
97
- pub fn split ( & self ) -> Result < [ Cidr ; 2 ] , Error > {
98
- let prefix = self . prefix + 1 ;
99
- Ok ( [
100
- Self :: new ( self . network , prefix) ?,
101
- Self :: new ( self . mid ( ) , prefix) ?,
102
- ] )
96
+ pub fn left_subnet ( & self ) -> Option < Cidr > {
97
+ match self . prefix as u32 {
98
+ u32:: BITS => None ,
99
+ _ => Some ( Self {
100
+ network : self . network ,
101
+ prefix : self . prefix + 1 ,
102
+ } ) ,
103
+ }
104
+ }
105
+
106
+ pub fn right_subnet ( & self ) -> Option < Cidr > {
107
+ match self . prefix as u32 {
108
+ u32:: BITS => None ,
109
+ _ => {
110
+ let prefix = self . prefix + 1 ;
111
+ let shift = u32:: BITS - prefix as u32 ;
112
+ Some ( Self {
113
+ network : ( ( ( u32:: from ( self . network ) >> shift) | 1 ) << shift) . into ( ) ,
114
+ prefix : prefix,
115
+ } )
116
+ }
117
+ }
118
+ }
119
+
120
+ pub fn split ( & self ) -> Option < [ Cidr ; 2 ] > {
121
+ match ( self . left_subnet ( ) , self . right_subnet ( ) ) {
122
+ ( Some ( left) , Some ( right) ) => Some ( [ left, right] ) ,
123
+ _ => None ,
124
+ }
103
125
}
104
126
}
105
127
@@ -140,46 +162,70 @@ impl FromStr for Cidr {
140
162
. map_err ( |e| Error :: Parse ( e. to_string ( ) ) ) ?,
141
163
)
142
164
} else {
143
- Err ( Error :: Parse ( "missing network prefix delimiter" . to_owned ( ) ) )
165
+ Err ( Error :: Parse ( "missing network prefix delimiter" . to_string ( ) ) )
144
166
}
145
167
}
146
168
}
147
169
148
- #[ cfg( test) ]
149
- mod tests {
150
- use super :: * ;
151
-
152
- // #[test]
153
- // fn cidr_constructor() {
154
- // for prefix in 0..=32 {
155
- // println!("{}", Cidr::new(Ipv4Addr::new(0b10000000, 0, 0, 0), prefix).unwrap());
156
- // println!("{}", Cidr::new(Ipv4Addr::new(0xFF, 0xFF, 0xFF, 0xFF), prefix).unwrap());
157
- // }
158
- // }
159
-
160
- // #[test]
161
- // fn cidr_first() {
162
- // let cidr: Cidr = "10.0.0.0/8".parse().unwrap();
163
- // println!("{} / {} : {} -> {}", cidr.network(), cidr.prefix(), cidr.first(), cidr.last());
164
- // let cidr: Cidr = "10.0.0.0/9".parse().unwrap();
165
- // println!("{} / {} : {} -> {}", cidr.network(), cidr.prefix(), cidr.first(), cidr.last());
166
- // let cidr: Cidr = "10.128.0.0/9".parse().unwrap();
167
- // println!("{} / {} : {} -> {}", cidr.network(), cidr.prefix(), cidr.first(), cidr.last());
168
- // let cidr: Cidr = "10.128.0.0/8".parse().unwrap();
169
- // println!("{} / {} : {} -> {}", cidr.network(), cidr.prefix(), cidr.first(), cidr.last());
170
- // }
171
-
172
- #[ test]
173
- fn it_works ( ) {
174
- // let c: Cidr = "10.0.0.0/8".parse().unwrap();
175
- // let [l, r] = c.split().unwrap();
176
- // println!("{l}, {r}");
177
- // for i in 0..=32 {
178
- // println!("{} {}", i / 8, i % 8);
179
- // }
180
- // let o = 127_u8;
181
- // println!("{}", o == o >> 1 << 1);
182
- // println!("{}", "127.0.343.0".parse::<Ipv4Addr>().unwrap());
183
- // println!("{}", "127.0.343.0".parse::<Cidr>().unwrap());
184
- }
185
- }
170
+ // #[cfg(test)]
171
+ // mod tests {
172
+ // use super::*;
173
+
174
+ // // #[test]
175
+ // // fn does_it_work() {
176
+ // // let cidr = Cidr::default();
177
+ // // println!("{cidr}");
178
+ // // println!("{:?}", cidr.parent());
179
+ // // println!("{:?}\n", cidr.split());
180
+ // // let cidr: Cidr = "0.0.0.0/0".parse().unwrap();
181
+ // // println!("{cidr}");
182
+ // // println!("{:?}", cidr.parent());
183
+ // // println!("{:?}\n", cidr.split());
184
+ // // let cidr: Cidr = "48.0.0.0/4".parse().unwrap();
185
+ // // println!("{cidr}");
186
+ // // println!("{:?}", cidr.parent());
187
+ // // println!("{:?}\n", cidr.split());
188
+ // // let cidr: Cidr = "10.0.128.0/25".parse().unwrap();
189
+ // // println!("{cidr}");
190
+ // // println!("{:?}", cidr.parent());
191
+ // // println!("{:?}\n", cidr.split());
192
+ // // let cidr: Cidr = "255.255.255.255/32".parse().unwrap();
193
+ // // println!("{cidr}");
194
+ // // println!("{:?}", cidr.parent());
195
+ // // println!("{:?}", cidr.split());
196
+ // // }
197
+
198
+ // // #[test]
199
+ // // fn cidr_constructor() {
200
+ // // for prefix in 0..=32 {
201
+ // // println!("{}", Cidr::new(Ipv4Addr::new(0b10000000, 0, 0, 0), prefix).unwrap());
202
+ // // println!("{}", Cidr::new(Ipv4Addr::new(0xFF, 0xFF, 0xFF, 0xFF), prefix).unwrap());
203
+ // // }
204
+ // // }
205
+
206
+ // // #[test]
207
+ // // fn cidr_first() {
208
+ // // let cidr: Cidr = "10.0.0.0/8".parse().unwrap();
209
+ // // println!("{} / {} : {} -> {}", cidr.network(), cidr.prefix(), cidr.first(), cidr.last());
210
+ // // let cidr: Cidr = "10.0.0.0/9".parse().unwrap();
211
+ // // println!("{} / {} : {} -> {}", cidr.network(), cidr.prefix(), cidr.first(), cidr.last());
212
+ // // let cidr: Cidr = "10.128.0.0/9".parse().unwrap();
213
+ // // println!("{} / {} : {} -> {}", cidr.network(), cidr.prefix(), cidr.first(), cidr.last());
214
+ // // let cidr: Cidr = "10.128.0.0/8".parse().unwrap();
215
+ // // println!("{} / {} : {} -> {}", cidr.network(), cidr.prefix(), cidr.first(), cidr.last());
216
+ // // }
217
+
218
+ // // #[test]
219
+ // // fn it_works() {
220
+ // // let c: Cidr = "10.0.0.0/8".parse().unwrap();
221
+ // // let [l, r] = c.split().unwrap();
222
+ // // println!("{l}, {r}");
223
+ // // for i in 0..=32 {
224
+ // // println!("{} {}", i / 8, i % 8);
225
+ // // }
226
+ // // let o = 127_u8;
227
+ // // println!("{}", o == o >> 1 << 1);
228
+ // // println!("{}", "127.0.343.0".parse::<Ipv4Addr>().unwrap());
229
+ // // println!("{}", "127.0.343.0".parse::<Cidr>().unwrap());
230
+ // // }
231
+ // }
0 commit comments