Be more idiomatic

This commit is contained in:
Keenan Tims 2023-03-20 17:46:00 -07:00
parent 4897aad492
commit 675cda945f
Signed by: ktims
GPG Key ID: 11230674D69038D4
3 changed files with 78 additions and 70 deletions

22
Cargo.lock generated
View File

@ -61,9 +61,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.0.1"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5dd14596c0e5b954530d0e6f1fd99b89c03e313aa2086e8da4303701a09e1cf"
checksum = "487f1e0fcbe47deb8b0574e646def1c903389d95241dd1bbcc6ce4a715dfc0c1"
[[package]]
name = "bstr"
@ -95,7 +95,7 @@ version = "4.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42dfd32784433290c51d92c438bb72ea5063797fc3cc9a21a8c4346bebbb2098"
dependencies = [
"bitflags 2.0.1",
"bitflags 2.0.2",
"clap_derive",
"clap_lex",
"is-terminal",
@ -365,9 +365,9 @@ dependencies = [
[[package]]
name = "io-lifetimes"
version = "1.0.8"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0dd6da19f25979c7270e70fa95ab371ec3b701cd0eefc47667a09785b3c59155"
checksum = "09270fd4fa1111bc614ed2246c7ef56239a3063d5be0d1ec3b589c505d400aeb"
dependencies = [
"hermit-abi",
"libc",
@ -466,9 +466,9 @@ checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
[[package]]
name = "os_str_bytes"
version = "6.4.1"
version = "6.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee"
checksum = "ceedf44fb00f2d1984b0bc98102627ce622e083e49a5bacdb3e514fa4238e267"
[[package]]
name = "pin-project-lite"
@ -639,9 +639,9 @@ dependencies = [
[[package]]
name = "rustix"
version = "0.36.10"
version = "0.36.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fe885c3a125aa45213b68cc1472a49880cb5923dc23f522ad2791b882228778"
checksum = "db4165c9963ab29e422d6c26fbc1d37f15bace6b2810221f9d925023480fcf0e"
dependencies = [
"bitflags 1.3.2",
"errno",
@ -668,9 +668,9 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed"
[[package]]
name = "serde"
version = "1.0.157"
version = "1.0.158"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "707de5fcf5df2b5788fca98dd7eab490bc2fd9b7ef1404defc462833b83f25ca"
checksum = "771d4d9c4163ee138805e12c710dd365e4f44be8be0503cb1bb9eb989425d9c9"
[[package]]
name = "slab"

View File

@ -19,7 +19,7 @@ impl IpBothRange {
IpBothRange::default()
}
pub fn add(&mut self, net: IpOrNet) {
match net.net {
match net.0 {
IpNet::V4(v4_net) => drop(self.v4.add(v4_net)),
IpNet::V6(v6_net) => drop(self.v6.add(v6_net)),
}
@ -90,9 +90,7 @@ impl<'a> IntoIterator for &'a IpBothRange {
}
#[derive(Debug, PartialEq)]
pub struct IpOrNet {
pub net: IpNet,
}
pub struct IpOrNet(IpNet);
#[derive(Debug, Clone)]
pub struct NetParseError {
@ -113,33 +111,29 @@ impl IpOrNet {
// netmask - 1.1.1.0/255.255.255.0
// wildcard mask - 1.1.1.0/0.0.0.255
fn parse_mask(p: &str) -> Result<u8, Box<dyn Error>> {
let mask = p.parse::<Ipv4Addr>();
match mask {
Ok(mask) => {
let intrep: u32 = mask.into();
let lead_ones = intrep.leading_ones();
if lead_ones > 0 {
if lead_ones + intrep.trailing_zeros() == 32 {
Ok(lead_ones.try_into()?)
} else {
Err(Box::new(NetParseError {
msg: "Invalid subnet mask".to_owned(),
}))
}
} else {
let lead_zeros = intrep.leading_zeros();
if lead_zeros + intrep.trailing_ones() == 32 {
Ok(lead_zeros.try_into()?)
} else {
Err(Box::new(NetParseError {
msg: "Invalid wildcard mask".to_owned(),
}))
}
}
let mask = p.parse::<Ipv4Addr>()?;
let intrep: u32 = mask.into();
let lead_ones = intrep.leading_ones();
if lead_ones > 0 {
if lead_ones + intrep.trailing_zeros() == 32 {
Ok(lead_ones.try_into()?)
} else {
Err(Box::new(NetParseError {
msg: "Invalid subnet mask".to_owned(),
}))
}
} else {
let lead_zeros = intrep.leading_zeros();
if lead_zeros + intrep.trailing_ones() == 32 {
Ok(lead_zeros.try_into()?)
} else {
Err(Box::new(NetParseError {
msg: "Invalid wildcard mask".to_owned(),
}))
}
Err(e) => Err(Box::new(e)),
}
}
fn from_parts(ip: &str, pfxlen: &str) -> Result<Self, Box<dyn Error>> {
let ip = ip.parse::<IpAddr>()?;
let pfxlenp = pfxlen.parse::<u8>();
@ -158,13 +152,25 @@ impl IpOrNet {
}
}
pub fn prefix_len(&self) -> u8 {
self.net.prefix_len()
self.0.prefix_len()
}
pub fn is_ipv4(&self) -> bool {
self.net.network().is_ipv4()
match self.0 {
IpNet::V4(_) => true,
IpNet::V6(_) => false,
}
}
pub fn is_ipv6(&self) -> bool {
self.net.network().is_ipv6()
match self.0 {
IpNet::V4(_) => false,
IpNet::V6(_) => true,
}
}
pub fn addr(&self) -> IpAddr {
self.0.addr()
}
pub fn network(&self) -> IpAddr {
self.0.network()
}
}
@ -181,47 +187,43 @@ impl FromStr for IpOrNet {
impl Display for IpOrNet {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.net.fmt(f)
self.0.fmt(f)
}
}
impl From<IpNet> for IpOrNet {
fn from(net: IpNet) -> Self {
IpOrNet { net }
IpOrNet(net)
}
}
impl From<IpAddr> for IpOrNet {
fn from(addr: IpAddr) -> Self {
IpOrNet { net: addr.into() }
IpOrNet(addr.into())
}
}
impl From<Ipv4Net> for IpOrNet {
fn from(net: Ipv4Net) -> Self {
IpOrNet { net: net.into() }
IpOrNet(net.into())
}
}
impl From<Ipv6Net> for IpOrNet {
fn from(net: Ipv6Net) -> Self {
IpOrNet { net: net.into() }
IpOrNet(net.into())
}
}
impl From<Ipv4Addr> for IpOrNet {
fn from(addr: Ipv4Addr) -> Self {
IpOrNet {
net: IpAddr::from(addr).into(),
}
IpOrNet(IpAddr::from(addr).into())
}
}
impl From<Ipv6Addr> for IpOrNet {
fn from(addr: Ipv6Addr) -> Self {
IpOrNet {
net: IpAddr::from(addr).into(),
}
IpOrNet(IpAddr::from(addr).into())
}
}
@ -245,7 +247,7 @@ impl Display for PrefixlenPair {
impl PartialEq<IpOrNet> for PrefixlenPair {
fn eq(&self, other: &IpOrNet) -> bool {
match other.net {
match other.0 {
IpNet::V4(net) => self.v4 == net.prefix_len(),
IpNet::V6(net) => self.v6 == net.prefix_len(),
}
@ -260,31 +262,31 @@ impl PartialEq<PrefixlenPair> for PrefixlenPair {
impl PartialOrd<IpOrNet> for PrefixlenPair {
fn ge(&self, other: &IpOrNet) -> bool {
match other.net {
match other.0 {
IpNet::V4(net) => self.v4 >= net.prefix_len(),
IpNet::V6(net) => self.v6 >= net.prefix_len(),
}
}
fn gt(&self, other: &IpOrNet) -> bool {
match other.net {
match other.0 {
IpNet::V4(net) => self.v4 > net.prefix_len(),
IpNet::V6(net) => self.v6 > net.prefix_len(),
}
}
fn le(&self, other: &IpOrNet) -> bool {
match other.net {
match other.0 {
IpNet::V4(net) => self.v4 <= net.prefix_len(),
IpNet::V6(net) => self.v6 <= net.prefix_len(),
}
}
fn lt(&self, other: &IpOrNet) -> bool {
match other.net {
match other.0 {
IpNet::V4(net) => self.v4 < net.prefix_len(),
IpNet::V6(net) => self.v6 < net.prefix_len(),
}
}
fn partial_cmp(&self, other: &IpOrNet) -> Option<std::cmp::Ordering> {
match other.net {
match other.0 {
IpNet::V4(net) => self.v4.partial_cmp(&net.prefix_len()),
IpNet::V6(net) => self.v6.partial_cmp(&net.prefix_len()),
}

View File

@ -1,6 +1,8 @@
extern crate ipnet;
extern crate iprange;
use std::process::exit;
mod iputils;
use iputils::{IpBothRange, IpOrNet, PrefixlenPair};
@ -72,7 +74,7 @@ impl App {
// Parser accepts host bits set, so detect that case and error if not truncate mode
// Note: aggregate6 errors in this case regardless of -4, -6 so do the same
if !self.args.truncate {
if pfx.net.addr() != pfx.net.network() {
if pfx.addr() != pfx.network() {
eprintln!("ERROR: '{}' is not a valid IP network, ignoring.", pfx);
return;
}
@ -89,18 +91,22 @@ impl App {
}
fn consume_input(&mut self, input: &mut Input) {
for line in input.lock().lines() {
for net in line.unwrap().split_whitespace().to_owned() {
let pnet = net.parse::<IpOrNet>();
match pnet {
Ok(pnet) => self.add_prefix(pnet),
Err(_e) => {
// self.errors.push(IpParseError {
// ip: net.to_string(),
// problem: e.to_string(),
// });
eprintln!("ERROR: '{}' is not a valid IP network, ignoring.", net);
match line {
Ok(line) => {
for net in line.split_whitespace() {
let pnet = net.parse::<IpOrNet>();
match pnet {
Ok(pnet) => self.add_prefix(pnet),
Err(_e) => {
eprintln!("ERROR: '{}' is not a valid IP network, ignoring.", net);
}
}
}
}
Err(e) => {
eprintln!("I/O error! {}", e);
exit(1);
}
}
}
}