use std::path::PathBuf;
use thiserror::Error as ThisError;
pub const SANDBOX_MISCONFIGURATION_EXIT_CODE: i32 = 2;
#[derive(Debug, ThisError)]
pub enum Error {
#[error("missing command")]
MissingCommand,
#[error("invalid cwd: {0}")]
InvalidCwd(PathBuf),
#[error("sandbox hardening failed: {0}")]
Hardening(#[source] std::io::Error),
#[error("failed to spawn child command: {0}")]
Spawn(#[source] std::io::Error),
#[error("failed to wait for child command: {0}")]
Wait(#[source] std::io::Error),
#[error(transparent)]
SandboxPolicy(#[from] heimdall_sandbox_policy::Error),
#[cfg(target_os = "linux")]
#[error(transparent)]
LinuxSandbox(#[from] heimdall_linux_sandbox::Error),
#[cfg(target_os = "macos")]
#[error(transparent)]
MacosSandbox(#[from] heimdall_macos_sandbox::Error),
#[error("sandbox misconfiguration: {0}")]
SandboxMisconfiguration(String),
}
impl Error {
#[must_use]
pub const fn missing_command() -> Self {
Self::MissingCommand
}
#[must_use]
pub fn invalid_cwd(cwd: PathBuf) -> Self {
Self::InvalidCwd(cwd)
}
#[must_use]
pub fn hardening(error: std::io::Error) -> Self {
Self::Hardening(error)
}
#[must_use]
pub fn spawn(error: std::io::Error) -> Self {
Self::Spawn(error)
}
#[must_use]
pub fn sandbox_misconfiguration(message: impl Into<String>) -> Self {
Self::SandboxMisconfiguration(message.into())
}
#[must_use]
pub const fn exit_code(&self) -> i32 {
match self {
Self::MissingCommand
| Self::InvalidCwd(_)
| Self::Hardening(_)
| Self::Spawn(_)
| Self::Wait(_)
| Self::SandboxPolicy(_)
| Self::SandboxMisconfiguration(_) => SANDBOX_MISCONFIGURATION_EXIT_CODE,
#[cfg(target_os = "linux")]
Self::LinuxSandbox(_) => SANDBOX_MISCONFIGURATION_EXIT_CODE,
#[cfg(target_os = "macos")]
Self::MacosSandbox(_) => SANDBOX_MISCONFIGURATION_EXIT_CODE,
}
}
}
#[cfg(test)]
mod tests {
use std::io;
use super::*;
#[test]
fn runtime_errors_map_to_documented_exit_codes() {
assert_eq!(
Error::missing_command().exit_code(),
SANDBOX_MISCONFIGURATION_EXIT_CODE
);
assert_eq!(
Error::invalid_cwd(PathBuf::from("missing")).exit_code(),
SANDBOX_MISCONFIGURATION_EXIT_CODE
);
assert_eq!(
Error::hardening(io::Error::other("failed")).exit_code(),
SANDBOX_MISCONFIGURATION_EXIT_CODE
);
assert_eq!(
Error::spawn(io::Error::other("failed")).exit_code(),
SANDBOX_MISCONFIGURATION_EXIT_CODE
);
}
}