consolex 0.1.0

Windows console utilities: probe, create, and release the console of the current process, plus a small CLI.
//! CLI for `consolex`.
//!
//! The binary is built as a GUI-subsystem executable (no console window on
//! launch). Console behavior is resolved at runtime:
//!
//! * **No arguments, no terminal** (double-clicked / third-party pipes) —
//!   runs silently: no window, no output.
//! * **Launched from an existing terminal** — behaves as a normal CLI
//!   program, with output going to that terminal.
//! * **With arguments and no terminal** — opens a new console window and
//!   displays the output.
//! * **`--hide`** — detaches and exits without output.

#![cfg_attr(windows, windows_subsystem = "windows")]

use std::env;
use std::process::ExitCode;

use clap::Parser;
use consolex::{self as cx, Mode};

/// Windows console control utility.
#[derive(Parser)]
#[command(version)]
struct Cli {
    /// Open a new console window.
    #[arg(long, conflicts_with = "hide")]
    show: bool,

    /// Detach the console and exit without output.
    #[arg(long)]
    hide: bool,
}

fn main() -> ExitCode {
    let raw: Vec<String> = env::args().skip(1).collect();

    // Resolve the console policy before clap prints anything, so that
    // --help/--version output is visible when launched without a console:
    //   - `--hide` → detach and exit silently.
    //   - any arguments → show output (a new window when no console is
    //     present; otherwise the existing terminal).
    //   - no arguments → silent (GUI default); normal CLI in a terminal.
    let mode: Mode = raw.iter().collect();
    let created = match cx::init(mode) {
        Ok(created) => created,
        Err(e) => {
            eprintln!("consolex: {e}");
            return ExitCode::FAILURE;
        }
    };

    // `try_parse` (not `parse`) so a console created for --help/--version
    // stays open long enough to read the output.
    let code = match Cli::try_parse() {
        Ok(_cli) => {
            println!("{} {}", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION"));
            0
        }
        Err(e) => {
            let code = if e.use_stderr() { 1 } else { 0 };
            let _ = e.print();
            code
        }
    };

    // Keep a newly created window open long enough to read the output.
    if created {
        let _ = cx::wait_key();
    }

    ExitCode::from(code as u8)
}