iwconf-win 0.1.2

A colorful, iwconfig-style WLAN CLI for Windows, backed by the native WLAN API (no netsh required).
use clap::Parser;

/// `iwconf` — an iwconfig-flavored WLAN tool for Windows.
///
/// With no flags, shows every wireless interface and its current
/// connection (richer than `netsh wlan show interface`, colors + emoji).
/// With `-i/--iface`, narrows to one interface by exact name, wildcard
/// (`Wi-Fi*`), or regex (`--regex`). The rest of the flags mirror
/// Linux `iwconfig`/`iwlist` where a Windows equivalent exists:
/// `essid` to associate, `key` for the passphrase, `--scan` to list
/// visible networks, `--disconnect` to drop the link.
#[derive(Parser, Debug)]
#[command(
    name = "iwconf",
    about = "Colorful iwconfig-style WLAN control for Windows",
    long_about = None,
    styles = clap_color_help::default_styles(),
    arg_required_else_help = false,
)]
pub struct Cli {
    /// Select interface by exact name, wildcard (`Wi-Fi*`, `Ether?`), or pattern.
    /// If the pattern matches more than one interface, all matches are listed
    /// and you're asked to narrow it down.
    #[arg(short = 'i', long = "iface", value_name = "NAME|PATTERN", global = true)]
    pub iface: Option<String>,

    /// Treat --iface as a regular expression instead of a glob-style wildcard.
    #[arg(long = "regex", requires = "iface", global = true)]
    pub regex: bool,

    /// Scan for and list visible networks (like `iwlist <if> scan`).
    #[arg(short = 's', long = "scan")]
    pub scan: bool,

    /// Force a fresh scan before showing results (otherwise the driver's
    /// cached scan list is used, which may be a few seconds/minutes stale).
    #[arg(long = "rescan")]
    pub rescan: bool,

    /// Associate with this SSID (like `iwconfig <if> essid <name>`).
    /// Combine with --key for secured networks, or --profile to reuse a
    /// profile already known to Windows.
    #[arg(long = "essid", value_name = "SSID")]
    pub essid: Option<String>,

    /// Passphrase for --essid on WPA2/WPA3-Personal networks.
    #[arg(long = "key", value_name = "PASSPHRASE", requires = "essid")]
    pub key: Option<String>,

    /// Use an existing saved Windows profile name instead of raw SSID+key.
    #[arg(long = "profile", value_name = "PROFILE", conflicts_with = "key")]
    pub profile: Option<String>,

    /// Disconnect the selected interface.
    #[arg(short = 'd', long = "disconnect")]
    pub disconnect: bool,

    /// Timeout in seconds to wait for a connect attempt to settle.
    /// Defaults to the configured `connect_timeout` (15s if unset).
    #[arg(long = "timeout", value_name = "SECS")]
    pub timeout: Option<u64>,

    /// Disable all ANSI colors.
    #[arg(long = "no-color", global = true)]
    pub no_color: bool,

    /// Disable emoji glyphs but keep colors.
    #[arg(long = "no-emoji", global = true)]
    pub no_emoji: bool,

    /// Plain, script-friendly output (implies --no-color --no-emoji).
    #[arg(long = "plain", global = true)]
    pub plain: bool,

    /// Print machine-readable JSON instead of the human view.
    #[arg(long = "json", global = true)]
    pub json: bool,
}

impl Cli {
    /// True if the invocation asks for any mutating action (connect/disconnect)
    /// rather than a read-only show/scan.
    pub fn is_action(&self) -> bool {
        self.essid.is_some() || self.disconnect
    }
}