stax 0.96.3

Fast stacked Git branches and PRs
Documentation
use crate::errors::{ConflictStopped, SilentExit, StaxError, exit_codes};
use std::process::ExitCode;

pub fn run() -> ExitCode {
    ExitCode::from(exit_code(crate::cli::run()) as u8)
}

fn exit_code(result: anyhow::Result<()>) -> i32 {
    let Err(err) = result else {
        return exit_codes::SUCCESS;
    };

    if let Some(status) = err.downcast_ref::<SilentExit>() {
        return status.0;
    }

    if err.downcast_ref::<ConflictStopped>().is_some() {
        return exit_codes::CONFLICT;
    }

    if let Some(stax_err) = err.downcast_ref::<StaxError>() {
        eprintln!("Error: {stax_err}");
        return stax_err.exit_code();
    }

    eprintln!("Error: {err:#}");
    exit_codes::GENERAL
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn success_maps_to_zero() {
        assert_eq!(exit_code(Ok(())), exit_codes::SUCCESS);
    }

    #[test]
    fn silent_exit_preserves_requested_code() {
        assert_eq!(
            exit_code(Err(SilentExit(exit_codes::VALIDATION).into())),
            exit_codes::VALIDATION
        );
    }

    #[test]
    fn conflict_stop_maps_to_conflict_code() {
        assert_eq!(exit_code(Err(ConflictStopped.into())), exit_codes::CONFLICT);
    }
}