cao 0.1.0

Update DNS record.

use if_addrs::{get_if_addrs, IfAddr, Interface};
use crate::error::Error;


fn interface_ip(interface: String) -> Result<String, Error> {
    let result = get_if_addrs()?;

    let opts: Vec<&str> = interface.split(',').map(|s| s.trim()).collect();
    let name = opts[0].clone();

    let filter_name = |i: Interface| {
        if i.name.eq(name) && !i.is_loopback() { Some(i.addr) }
        else { None }
    };

    let filter_ip_type = if opts.len() >= 2 {
        if opts[1].eq("4") {
            |ip: &IfAddr| if let IfAddr::V4(_) = ip { true } else { false }
        } else if opts[1].eq("6") {
            |ip: &IfAddr| if let IfAddr::V6(_) = ip { true } else { false }
        } else {
            |_: &IfAddr| true
        }
    } else {
        |_: &IfAddr| true
    };

    let mut list = result
        .into_iter()
        .filter_map(filter_name)
        .filter(filter_ip_type)
        .map(|ip| {
            match ip {
                IfAddr::V4(ip) => format!("{}", ip.ip),
                IfAddr::V6(ip) => format!("{}", ip.ip),
            }
        })
        .filter
        (|s| !(opts.len() >= 3 && !s.starts_with(opts[2])));

    let nth = if opts.len() >= 4 {
        let n = opts[3].parse().unwrap_or(0);
        list.nth(n)
    } else {
        list.next()
    };
    nth.ok_or(Error::InterfaceFilterError(format!("No such interface: {}", interface)))
}

pub fn interface_or_value(interface: Option<String>, value: Option<String>) -> Result<String, Error> {
    if value.is_some() {
        Ok(value.unwrap())
    } else {
        let interface = interface.ok_or(Error::MissingRequiredArgument)?;
        interface_ip(interface)
    }
}

pub fn interface_list(interface: Option<String>) -> Result<Vec<(String, String)>, Error> {
    if let Some(interface) = interface {
        let s = interface_ip(interface.clone())?;
        Ok(vec![(interface, s)])
    } else {
        Ok(get_if_addrs()?
            .into_iter()
            .map(|i| (i.name, format!("{:?}", i.addr)))
            .collect()
        )
    }
}