From ee51bb7d3d335804d49b4db8d38cbbf9927e090c Mon Sep 17 00:00:00 2001 From: _ <_@_> Date: Thu, 9 Dec 2021 00:11:47 +0000 Subject: [PATCH] :recycle: refactor: move more Windows-only code behind cfg flags --- src/ip.rs | 134 ++++++++++++++++++++++++++++++++-------------------- src/main.rs | 8 ++-- 2 files changed, 87 insertions(+), 55 deletions(-) diff --git a/src/ip.rs b/src/ip.rs index b3470c4..9fe9dca 100644 --- a/src/ip.rs +++ b/src/ip.rs @@ -6,57 +6,89 @@ use std::{ use crate::AppError; -pub fn get_ip_addr_output () -> Result { - let output = Command::new ("ip") - .arg ("addr") - .output ()?; - let output = output.stdout.as_slice (); - let output = String::from_utf8 (output.to_vec ())?; - Ok (output) -} - -pub fn parse_ip_addr_output (output: &str) -> Vec { - // I wrote this in FP style because I was bored. +#[cfg(target_os = "linux")] +pub mod linux { + use super::*; - output.lines () - .map (|l| l.trim_start ()) - .filter_map (|l| l.strip_prefix ("inet ")) - .filter_map (|l| l.find ('/').map (|x| &l [0..x])) - .filter_map (|l| Ipv4Addr::from_str (l).ok ()) - .collect () -} - -pub fn get_ip_config_output () -> Result { - let output = Command::new ("ipconfig") - .output ()?; - let output = output.stdout.as_slice (); - let output = String::from_utf8 (output.to_vec ())?; - Ok (output) -} - -pub fn parse_ip_config_output (output: &str) -> Vec { - let mut addrs = vec! []; - - for line in output.lines () { - let line = line.trim_start (); - - // Maybe only works on English locales? - if ! line.starts_with ("IPv4 Address") { - continue; - } - let colon_pos = match line.find (':') { - None => continue, - Some (x) => x, - }; - let line = &line [colon_pos + 2..]; - - let addr = match Ipv4Addr::from_str (line) { - Err (_) => continue, - Ok (x) => x, - }; - - addrs.push (addr); + pub fn get_ip_addr_output () -> Result { + let output = Command::new ("ip") + .arg ("addr") + .output ()?; + let output = output.stdout.as_slice (); + let output = String::from_utf8 (output.to_vec ())?; + Ok (output) + } + + pub fn parse_ip_addr_output (output: &str) -> Vec { + // I wrote this in FP style because I was bored. + + output.lines () + .map (|l| l.trim_start ()) + .filter_map (|l| l.strip_prefix ("inet ")) + .filter_map (|l| l.find ('/').map (|x| &l [0..x])) + .filter_map (|l| Ipv4Addr::from_str (l).ok ()) + .collect () + } +} + +#[cfg(target_os = "windows")] +pub mod windows { + use super::*; + + pub fn get_ip_config_output () -> Result { + let output = Command::new ("ipconfig") + .output ()?; + let output = output.stdout.as_slice (); + let output = String::from_utf8 (output.to_vec ())?; + Ok (output) + } + + pub fn parse_ip_config_output (output: &str) -> Vec { + let mut addrs = vec! []; + + for line in output.lines () { + let line = line.trim_start (); + + // Maybe only works on English locales? + if ! line.starts_with ("IPv4 Address") { + continue; + } + let colon_pos = match line.find (':') { + None => continue, + Some (x) => x, + }; + let line = &line [colon_pos + 2..]; + + let addr = match Ipv4Addr::from_str (line) { + Err (_) => continue, + Ok (x) => x, + }; + + addrs.push (addr); + } + + addrs + } + + #[cfg (test)] + mod test { + use super::*; + + #[test] + fn test () { + for (input, expected) in [ + ( + r" + IPv4 Address . . .. . . . : 192.168.1.1 + ", + vec! [ + Ipv4Addr::new (192, 168, 1, 1), + ] + ), + ] { + let actual = parse_ip_config_output (input); + assert_eq! (actual, expected); + } + } } - - addrs } diff --git a/src/main.rs b/src/main.rs index e025d29..55d8cf4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -111,9 +111,9 @@ async fn async_main () -> Result <(), AppError> { #[cfg(target_os = "linux")] fn my_ips () -> Result <(), AppError> { - let output = ip::get_ip_addr_output ()?; + let output = ip::linux::get_ip_addr_output ()?; - for addr in ip::parse_ip_addr_output (&output) + for addr in ip::linux::parse_ip_addr_output (&output) .iter () .filter (|a| ! a.is_loopback ()) { @@ -131,9 +131,9 @@ fn my_ips () -> Result <(), AppError> { #[cfg(target_os = "windows")] fn my_ips () -> Result <(), AppError> { - let output = ip::get_ip_config_output ()?; + let output = ip::windows::get_ip_config_output ()?; - for addr in ip::parse_ip_config_output (&output) { + for addr in ip::windows::parse_ip_config_output (&output) { println! ("{:?}", addr); }