whyno-cli 0.5.0

Linux permission debugger
/// Top-level error; all variants map to exit code 2.
#[derive(thiserror::Error, Debug)]
pub enum WhynoError {
    #[error("{0}")]
    Cli(#[from] CliError),
    #[error("{0}")]
    Output(#[from] OutputError),
    #[error("{0}")]
    Gather(#[from] whyno_gather::error::GatherError),
    #[error("caps: {0}")]
    Caps(String),
}

#[derive(thiserror::Error, Debug, PartialEq, Eq)]
pub enum CliError {
    #[error("invalid subject format: {0}")]
    InvalidSubject(String),
    #[error("unknown operation: {0}. Valid: read, write, execute, delete, create, stat, chmod, chown-uid, chown-gid, setxattr")]
    InvalidOperation(String),
    #[error("--json and --explain are mutually exclusive")]
    ConflictingFlags,
    #[error("unknown capability: {0}")]
    InvalidCap(String),
    #[error("unknown xattr key prefix: {0}. Valid prefixes: user., trusted., security., system.posix_acl_")]
    InvalidXattrKey(String),
    #[error("--xattr-key is required when op is setxattr")]
    MissingXattrKey,
    #[error("invalid --new-mode value: {0}. Provide an octal integer, e.g. 644 or 0644")]
    InvalidMode(String),
    #[error("missing required argument: {0}")]
    MissingArg(String),
}

#[derive(thiserror::Error, Debug)]
pub enum OutputError {
    #[error("write failed: {0}")]
    WriteFailed(#[from] std::io::Error),
    #[error("JSON serialization failed: {0}")]
    SerializationFailed(#[from] serde_json::Error),
}