use std::path::PathBuf;
#[derive(Debug, thiserror::Error)]
pub enum NucleusError {
#[error("Failed to create namespace: {0}")]
NamespaceError(String),
#[error("Failed to configure cgroup: {0}")]
CgroupError(String),
#[error("Failed to mount filesystem: {0}")]
FilesystemError(String),
#[error("Failed to pivot root: {0}")]
PivotRootError(String),
#[error("Failed to populate context: {0}")]
ContextError(String),
#[error("Failed to drop capabilities: {0}")]
CapabilityError(String),
#[error("Failed to apply seccomp filter: {0}")]
SeccompError(String),
#[error("Failed to apply Landlock policy: {0}")]
LandlockError(String),
#[error("Invalid resource limit: {0}")]
InvalidResourceLimit(String),
#[error("Resource error: {0}")]
ResourceError(String),
#[error("Configuration error: {0}")]
ConfigError(String),
#[error("Invalid path: {path:?}")]
InvalidPath { path: PathBuf },
#[error("Process execution failed: {0}")]
ExecError(String),
#[error("gVisor runtime error: {0}")]
GVisorError(String),
#[error("Container not found: {0}")]
ContainerNotFound(String),
#[error("Ambiguous container reference: {0}")]
AmbiguousContainer(String),
#[error("Checkpoint error: {0}")]
CheckpointError(String),
#[error("Network error: {0}")]
NetworkError(String),
#[error("Attach error: {0}")]
AttachError(String),
#[error("Permission denied: {0}")]
PermissionDenied(String),
#[error("Container not running: {0}")]
ContainerNotRunning(String),
#[error("Syscall error: {0}")]
SyscallError(#[from] nix::Error),
#[error("IO error: {0}")]
IoError(#[from] std::io::Error),
#[error("Invalid state transition: from {from} to {to}")]
InvalidStateTransition { from: String, to: String },
#[error("OCI hook failed: {0}")]
HookError(String),
#[error("JSON serialization error: {0}")]
SerdeJsonError(#[from] serde_json::Error),
}
pub type Result<T> = std::result::Result<T, NucleusError>;
pub trait StateTransition: std::fmt::Debug + Sized {
fn can_transition_to(&self, next: &Self) -> bool;
fn is_terminal(&self) -> bool;
fn transition(self, next: Self) -> Result<Self> {
if self.can_transition_to(&next) {
Ok(next)
} else {
Err(NucleusError::InvalidStateTransition {
from: format!("{:?}", self),
to: format!("{:?}", next),
})
}
}
}