From 675cda945fc04efaf896f2d4456dacee0ed275d1 Mon Sep 17 00:00:00 2001 From: Keenan Tims Date: Mon, 20 Mar 2023 17:46:00 -0700 Subject: [PATCH] Be more idiomatic --- Cargo.lock | 22 ++++++------ src/iputils.rs | 98 +++++++++++++++++++++++++------------------------- src/main.rs | 28 +++++++++------ 3 files changed, 78 insertions(+), 70 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 191b66e..361a4a0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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" diff --git a/src/iputils.rs b/src/iputils.rs index 027cd29..11e92ac 100644 --- a/src/iputils.rs +++ b/src/iputils.rs @@ -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> { - let mask = p.parse::(); - 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::()?; + 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> { let ip = ip.parse::()?; let pfxlenp = pfxlen.parse::(); @@ -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 for IpOrNet { fn from(net: IpNet) -> Self { - IpOrNet { net } + IpOrNet(net) } } impl From for IpOrNet { fn from(addr: IpAddr) -> Self { - IpOrNet { net: addr.into() } + IpOrNet(addr.into()) } } impl From for IpOrNet { fn from(net: Ipv4Net) -> Self { - IpOrNet { net: net.into() } + IpOrNet(net.into()) } } impl From for IpOrNet { fn from(net: Ipv6Net) -> Self { - IpOrNet { net: net.into() } + IpOrNet(net.into()) } } impl From for IpOrNet { fn from(addr: Ipv4Addr) -> Self { - IpOrNet { - net: IpAddr::from(addr).into(), - } + IpOrNet(IpAddr::from(addr).into()) } } impl From 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 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 for PrefixlenPair { impl PartialOrd 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 { - 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()), } diff --git a/src/main.rs b/src/main.rs index 5c70d67..fde5459 100644 --- a/src/main.rs +++ b/src/main.rs @@ -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::(); - 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::(); + 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); + } } } }