♻️ refactor: move more Windows-only code behind cfg flags

main
_ 2021-12-09 00:11:47 +00:00
parent dbedc6083e
commit ee51bb7d3d
2 changed files with 87 additions and 55 deletions

134
src/ip.rs
View File

@ -6,57 +6,89 @@ use std::{
use crate::AppError; use crate::AppError;
pub fn get_ip_addr_output () -> Result <String, AppError> { #[cfg(target_os = "linux")]
let output = Command::new ("ip") pub mod linux {
.arg ("addr") use super::*;
.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 <Ipv4Addr> {
// I wrote this in FP style because I was bored.
output.lines () pub fn get_ip_addr_output () -> Result <String, AppError> {
.map (|l| l.trim_start ()) let output = Command::new ("ip")
.filter_map (|l| l.strip_prefix ("inet ")) .arg ("addr")
.filter_map (|l| l.find ('/').map (|x| &l [0..x])) .output ()?;
.filter_map (|l| Ipv4Addr::from_str (l).ok ()) let output = output.stdout.as_slice ();
.collect () let output = String::from_utf8 (output.to_vec ())?;
} Ok (output)
}
pub fn get_ip_config_output () -> Result <String, AppError> {
let output = Command::new ("ipconfig") pub fn parse_ip_addr_output (output: &str) -> Vec <Ipv4Addr> {
.output ()?; // I wrote this in FP style because I was bored.
let output = output.stdout.as_slice ();
let output = String::from_utf8 (output.to_vec ())?; output.lines ()
Ok (output) .map (|l| l.trim_start ())
} .filter_map (|l| l.strip_prefix ("inet "))
.filter_map (|l| l.find ('/').map (|x| &l [0..x]))
pub fn parse_ip_config_output (output: &str) -> Vec <Ipv4Addr> { .filter_map (|l| Ipv4Addr::from_str (l).ok ())
let mut addrs = vec! []; .collect ()
}
for line in output.lines () { }
let line = line.trim_start ();
#[cfg(target_os = "windows")]
// Maybe only works on English locales? pub mod windows {
if ! line.starts_with ("IPv4 Address") { use super::*;
continue;
} pub fn get_ip_config_output () -> Result <String, AppError> {
let colon_pos = match line.find (':') { let output = Command::new ("ipconfig")
None => continue, .output ()?;
Some (x) => x, let output = output.stdout.as_slice ();
}; let output = String::from_utf8 (output.to_vec ())?;
let line = &line [colon_pos + 2..]; Ok (output)
}
let addr = match Ipv4Addr::from_str (line) {
Err (_) => continue, pub fn parse_ip_config_output (output: &str) -> Vec <Ipv4Addr> {
Ok (x) => x, let mut addrs = vec! [];
};
for line in output.lines () {
addrs.push (addr); 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
} }

View File

@ -111,9 +111,9 @@ async fn async_main () -> Result <(), AppError> {
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
fn my_ips () -> Result <(), AppError> { 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 () .iter ()
.filter (|a| ! a.is_loopback ()) .filter (|a| ! a.is_loopback ())
{ {
@ -131,9 +131,9 @@ fn my_ips () -> Result <(), AppError> {
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
fn my_ips () -> Result <(), AppError> { 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); println! ("{:?}", addr);
} }