Skip to content

Commit

Permalink
Merge pull request #19 from nicholaschiasson/minor/support-superset-c…
Browse files Browse the repository at this point in the history
…heck-feature

Add support to check if fcidr is superset of a cidr
  • Loading branch information
nicholaschiasson authored Nov 10, 2023
2 parents 6ec23e2 + bf9df49 commit f6d78ff
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 6 deletions.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ Usage: fcidr [CIDR] <COMMAND>
Commands:
complement Compute the complement of the input CIDR(s) [aliases: !, not]
difference Compute the set difference between the input CIDR(s) and another CIDR [aliases: -, exclude, minus]
superset Exits successfully if the input CIDR(s) is a superset of another CIDR [aliases: >, contains]
union Compute the set union of the input CIDR(s) and another CIDR [aliases: +, include, plus]
help Print this message or the help of the given subcommand(s)
Expand Down Expand Up @@ -119,6 +120,16 @@ fcidr 10.0.0.0/8 + 127.0.0.0/16 | fcidr - 10.64.0.0/16 | fcidr !
128.0.0.0/1
```

```
fcidr 255.0.0.0/16 contains "255.0.1.2/32" && echo Woohoo!
Woohoo!
```

```
echo 255.0.0.0/16 | fcidr contains "255.1.1.2/32" && echo Woohoo!
Error: "not a superset of 255.1.1.2/32"
```

## Development

### Prerequisites
Expand Down
16 changes: 11 additions & 5 deletions src/cidr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,14 +140,20 @@ impl Display for Cidr {
}
}

impl TryFrom<Ipv4Addr> for Cidr {
type Error = Error;

fn try_from(value: Ipv4Addr) -> Result<Self, Self::Error> {
Self::new(value, u32::BITS as u8)
impl From<Ipv4Addr> for Cidr {
fn from(value: Ipv4Addr) -> Self {
Self::new(value, u32::BITS as u8).expect("convert from Ipv4Addr")
}
}

// impl TryFrom<Ipv4Addr> for Cidr {
// type Error = Error;

// fn try_from(value: Ipv4Addr) -> Result<Self, Self::Error> {
// Self::new(value, u32::BITS as u8)
// }
// }

impl FromStr for Cidr {
type Err = Error;

Expand Down
21 changes: 21 additions & 0 deletions src/fcidr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,23 @@ impl CidrNode {
}
self
}

fn contains(&self, cidr: Cidr) -> bool {
if cidr.prefix() < self.cidr.prefix() {
return false;
}
match &self.inclusion {
Inclusion::Excluded => false,
Inclusion::Included => self.cidr.contains(cidr),
Inclusion::Subnets([left, right]) => {
if cidr.network() < self.cidr.mid() {
left.borrow().contains(cidr)
} else {
right.borrow().contains(cidr)
}
}
}
}
}

#[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd)]
Expand Down Expand Up @@ -139,6 +156,10 @@ impl Fcidr {
self
}

pub fn is_superset(&self, cidr: Cidr) -> bool {
self.cidr.borrow().contains(cidr)
}

pub fn union(&mut self, cidr: Cidr) -> &mut Self {
self.cidr
.borrow_mut()
Expand Down
11 changes: 10 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,11 @@ enum FcidrCommand {
/// The second CIDR range operand for the difference function
cidr: Cidr,
},
#[command(visible_alias = "+", visible_alias = "include", visible_alias = "plus")]
/// Exits successfully if the input CIDR(s) is a superset of another CIDR
#[command(visible_alias = ">", visible_alias = "contains")]
Superset { cidr: Cidr },
/// Compute the set union of the input CIDR(s) and another CIDR
#[command(visible_alias = "+", visible_alias = "include", visible_alias = "plus")]
Union {
/// The second CIDR range operand for the union function
cidr: Cidr,
Expand Down Expand Up @@ -65,6 +68,12 @@ fn main() -> Result<(), Box<dyn Error>> {
match cli.command {
FcidrCommand::Complement => fcidr.complement(),
FcidrCommand::Difference { cidr } => fcidr.difference(cidr),
FcidrCommand::Superset { cidr } => {
if fcidr.is_superset(cidr) {
return Ok(());
}
return Err(format!("not a superset of {cidr}").into());
}
FcidrCommand::Union { cidr } => fcidr.union(cidr),
};

Expand Down

0 comments on commit f6d78ff

Please sign in to comment.