Skip to content

Commit f6d78ff

Browse files
Merge pull request #19 from nicholaschiasson/minor/support-superset-check-feature
Add support to check if fcidr is superset of a cidr
2 parents 6ec23e2 + bf9df49 commit f6d78ff

File tree

4 files changed

+53
-6
lines changed

4 files changed

+53
-6
lines changed

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ Usage: fcidr [CIDR] <COMMAND>
3838
Commands:
3939
complement Compute the complement of the input CIDR(s) [aliases: !, not]
4040
difference Compute the set difference between the input CIDR(s) and another CIDR [aliases: -, exclude, minus]
41+
superset Exits successfully if the input CIDR(s) is a superset of another CIDR [aliases: >, contains]
4142
union Compute the set union of the input CIDR(s) and another CIDR [aliases: +, include, plus]
4243
help Print this message or the help of the given subcommand(s)
4344
@@ -119,6 +120,16 @@ fcidr 10.0.0.0/8 + 127.0.0.0/16 | fcidr - 10.64.0.0/16 | fcidr !
119120
128.0.0.0/1
120121
```
121122

123+
```
124+
fcidr 255.0.0.0/16 contains "255.0.1.2/32" && echo Woohoo!
125+
Woohoo!
126+
```
127+
128+
```
129+
echo 255.0.0.0/16 | fcidr contains "255.1.1.2/32" && echo Woohoo!
130+
Error: "not a superset of 255.1.1.2/32"
131+
```
132+
122133
## Development
123134

124135
### Prerequisites

src/cidr.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -140,14 +140,20 @@ impl Display for Cidr {
140140
}
141141
}
142142

143-
impl TryFrom<Ipv4Addr> for Cidr {
144-
type Error = Error;
145-
146-
fn try_from(value: Ipv4Addr) -> Result<Self, Self::Error> {
147-
Self::new(value, u32::BITS as u8)
143+
impl From<Ipv4Addr> for Cidr {
144+
fn from(value: Ipv4Addr) -> Self {
145+
Self::new(value, u32::BITS as u8).expect("convert from Ipv4Addr")
148146
}
149147
}
150148

149+
// impl TryFrom<Ipv4Addr> for Cidr {
150+
// type Error = Error;
151+
152+
// fn try_from(value: Ipv4Addr) -> Result<Self, Self::Error> {
153+
// Self::new(value, u32::BITS as u8)
154+
// }
155+
// }
156+
151157
impl FromStr for Cidr {
152158
type Err = Error;
153159

src/fcidr.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,23 @@ impl CidrNode {
7272
}
7373
self
7474
}
75+
76+
fn contains(&self, cidr: Cidr) -> bool {
77+
if cidr.prefix() < self.cidr.prefix() {
78+
return false;
79+
}
80+
match &self.inclusion {
81+
Inclusion::Excluded => false,
82+
Inclusion::Included => self.cidr.contains(cidr),
83+
Inclusion::Subnets([left, right]) => {
84+
if cidr.network() < self.cidr.mid() {
85+
left.borrow().contains(cidr)
86+
} else {
87+
right.borrow().contains(cidr)
88+
}
89+
}
90+
}
91+
}
7592
}
7693

7794
#[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd)]
@@ -139,6 +156,10 @@ impl Fcidr {
139156
self
140157
}
141158

159+
pub fn is_superset(&self, cidr: Cidr) -> bool {
160+
self.cidr.borrow().contains(cidr)
161+
}
162+
142163
pub fn union(&mut self, cidr: Cidr) -> &mut Self {
143164
self.cidr
144165
.borrow_mut()

src/main.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,11 @@ enum FcidrCommand {
3232
/// The second CIDR range operand for the difference function
3333
cidr: Cidr,
3434
},
35-
#[command(visible_alias = "+", visible_alias = "include", visible_alias = "plus")]
35+
/// Exits successfully if the input CIDR(s) is a superset of another CIDR
36+
#[command(visible_alias = ">", visible_alias = "contains")]
37+
Superset { cidr: Cidr },
3638
/// Compute the set union of the input CIDR(s) and another CIDR
39+
#[command(visible_alias = "+", visible_alias = "include", visible_alias = "plus")]
3740
Union {
3841
/// The second CIDR range operand for the union function
3942
cidr: Cidr,
@@ -65,6 +68,12 @@ fn main() -> Result<(), Box<dyn Error>> {
6568
match cli.command {
6669
FcidrCommand::Complement => fcidr.complement(),
6770
FcidrCommand::Difference { cidr } => fcidr.difference(cidr),
71+
FcidrCommand::Superset { cidr } => {
72+
if fcidr.is_superset(cidr) {
73+
return Ok(());
74+
}
75+
return Err(format!("not a superset of {cidr}").into());
76+
}
6877
FcidrCommand::Union { cidr } => fcidr.union(cidr),
6978
};
7079

0 commit comments

Comments
 (0)