turtle-build 0.1.0

The Ninja build system clone written in Rust
use std::{
    error::Error,
    fmt::{self, Display, Formatter},
    path::Path,
};
use tokio::{io, task::JoinError};

#[derive(Clone, Debug)]
pub enum InfrastructureError {
    CommandExit(String, Option<i32>),
    DefaultOutputNotFound(String),
    Other(String),
    Sled(sled::Error),
}

impl InfrastructureError {
    pub fn with_path(error: io::Error, path: impl AsRef<Path>) -> Self {
        Self::Other(format!("{}: {}", error, path.as_ref().display()))
    }
}

impl Error for InfrastructureError {}

impl Display for InfrastructureError {
    fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
        match self {
            Self::CommandExit(command, code) => {
                write!(
                    formatter,
                    "command exited {}: {}",
                    if let Some(code) = code {
                        format!("with status code {}", code)
                    } else {
                        "without status code".into()
                    },
                    command
                )
            }
            Self::DefaultOutputNotFound(output) => {
                write!(formatter, "default output \"{}\" not found", output)
            }
            Self::Other(message) => write!(formatter, "{}", message),
            Self::Sled(error) => write!(formatter, "{}", error),
        }
    }
}

impl From<io::Error> for InfrastructureError {
    fn from(error: io::Error) -> Self {
        Self::Other(format!("{}", &error))
    }
}

impl From<JoinError> for InfrastructureError {
    fn from(error: JoinError) -> Self {
        Self::Other(format!("{}", &error))
    }
}

impl From<sled::Error> for InfrastructureError {
    fn from(error: sled::Error) -> Self {
        Self::Sled(error)
    }
}