➕ add `my-ips` impl for Linux and refactor it into a module
parent
cf283a2eaa
commit
2b4695934e
|
@ -0,0 +1,62 @@
|
||||||
|
use std::{
|
||||||
|
net::Ipv4Addr,
|
||||||
|
process::Command,
|
||||||
|
str::FromStr,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::AppError;
|
||||||
|
|
||||||
|
pub fn get_ip_addr_output () -> Result <String, AppError> {
|
||||||
|
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 <Ipv4Addr> {
|
||||||
|
// 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 ()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_ip_config_output () -> Result <String, AppError> {
|
||||||
|
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 <Ipv4Addr> {
|
||||||
|
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
|
||||||
|
}
|
53
src/main.rs
53
src/main.rs
|
@ -17,6 +17,7 @@ use mac_address::{
|
||||||
};
|
};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
|
mod ip;
|
||||||
mod message;
|
mod message;
|
||||||
mod tlv;
|
mod tlv;
|
||||||
|
|
||||||
|
@ -26,12 +27,14 @@ use message::{
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive (Debug, Error)]
|
#[derive (Debug, Error)]
|
||||||
enum AppError {
|
pub enum AppError {
|
||||||
#[error (transparent)]
|
#[error (transparent)]
|
||||||
AddrParse (#[from] std::net::AddrParseError),
|
AddrParse (#[from] std::net::AddrParseError),
|
||||||
#[error (transparent)]
|
#[error (transparent)]
|
||||||
CliArgs (#[from] CliArgError),
|
CliArgs (#[from] CliArgError),
|
||||||
#[error (transparent)]
|
#[error (transparent)]
|
||||||
|
FromUtf8 (#[from] std::string::FromUtf8Error),
|
||||||
|
#[error (transparent)]
|
||||||
Io (#[from] std::io::Error),
|
Io (#[from] std::io::Error),
|
||||||
#[error (transparent)]
|
#[error (transparent)]
|
||||||
MacAddr (#[from] mac_address::MacAddressError),
|
MacAddr (#[from] mac_address::MacAddressError),
|
||||||
|
@ -44,7 +47,7 @@ enum AppError {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive (Debug, Error)]
|
#[derive (Debug, Error)]
|
||||||
enum CliArgError {
|
pub enum CliArgError {
|
||||||
#[error ("Missing value for argument `{0}`")]
|
#[error ("Missing value for argument `{0}`")]
|
||||||
MissingArgumentValue (String),
|
MissingArgumentValue (String),
|
||||||
#[error ("First argument should be a subcommand")]
|
#[error ("First argument should be a subcommand")]
|
||||||
|
@ -100,7 +103,15 @@ fn main () -> Result <(), AppError> {
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
fn my_ips () -> Result <(), AppError> {
|
fn my_ips () -> Result <(), AppError> {
|
||||||
println! ("my-ips subcommand not implemented for linux yet");
|
let output = ip::get_ip_addr_output ()?;
|
||||||
|
|
||||||
|
for addr in ip::parse_ip_addr_output (&output)
|
||||||
|
.iter ()
|
||||||
|
.filter (|a| ! a.is_loopback ())
|
||||||
|
{
|
||||||
|
println! ("{:?}", addr);
|
||||||
|
}
|
||||||
|
|
||||||
Ok (())
|
Ok (())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,47 +123,15 @@ fn my_ips () -> Result <(), AppError> {
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
fn my_ips () -> Result <(), AppError> {
|
fn my_ips () -> Result <(), AppError> {
|
||||||
use std::process::Command;
|
let output = ip::get_ip_config_output ()?;
|
||||||
|
|
||||||
let output = Command::new ("ipconfig")
|
for addr in ip::parse_ip_config_output (&output) {
|
||||||
.output ()?;
|
|
||||||
let output = output.stdout.as_slice ();
|
|
||||||
let output = std::str::from_utf8 (output)?;
|
|
||||||
|
|
||||||
for addr in parse_ip_config_output (output) {
|
|
||||||
println! ("{:?}", addr);
|
println! ("{:?}", addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok (())
|
Ok (())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_ip_config_output (output: &str) -> Vec <Ipv4Addr> {
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ServerResponse {
|
struct ServerResponse {
|
||||||
mac: Option <[u8; 6]>,
|
mac: Option <[u8; 6]>,
|
||||||
nickname: Option <String>,
|
nickname: Option <String>,
|
||||||
|
|
Loading…
Reference in New Issue