whyno-cli 0.2.0

Linux permission debugger
//! Error types for whyno cli.
//!
//! Three domains unified under `WhynoError`:
//! - `CliError`: arg parsing and validation
//! - `OutputError`: formatting and I/O
//! - `Caps`: capability management

/// Top-level error unifying all cli failure modes.
///
/// All variants produce exit code 2.
#[derive(thiserror::Error, Debug)]
pub enum WhynoError {
    /// Arg parsing or validation error.
    #[error("{0}")]
    Cli(#[from] CliError),
    /// Output formatting or write error.
    #[error("{0}")]
    Output(#[from] OutputError),
    /// State gathering error (subject resolution, stat, mountinfo, etc.).
    #[error("{0}")]
    Gather(#[from] whyno_gather::error::GatherError),
    /// Caps management error.
    #[error("caps: {0}")]
    Caps(String),
}

/// Arg parsing and validation errors.
#[derive(thiserror::Error, Debug, PartialEq, Eq)]
pub enum CliError {
    /// Unparseable subject string.
    #[error("invalid subject format: {0}")]
    InvalidSubject(String),
    /// Unrecognized operation string.
    #[error("unknown operation: {0}. Valid: read, write, execute, delete, create, stat")]
    InvalidOperation(String),
    /// Mutually exclusive flags specified.
    #[error("--json and --explain are mutually exclusive")]
    ConflictingFlags,
    /// Unrecognized capability name passed to `--with-cap`.
    #[error("unknown capability: {0}")]
    InvalidCap(String),
}

/// Output formatting and write errors.
#[derive(thiserror::Error, Debug)]
pub enum OutputError {
    /// I/O write failure.
    #[error("write failed: {0}")]
    WriteFailed(#[from] std::io::Error),
    /// JSON serialization failure.
    #[error("JSON serialization failed: {0}")]
    SerializationFailed(#[from] serde_json::Error),
}