use super::super::vfs::Vfs;
use super::super::vm::SessionHolder;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RunResult {
Continue,
Exit,
}
pub struct ExecContext<'a> {
pub vfs: &'a mut Vfs,
pub stdin: &'a mut dyn std::io::Read,
pub stdout: &'a mut dyn std::io::Write,
pub stderr: &'a mut dyn std::io::Write,
pub vm_session: &'a mut SessionHolder,
}
#[derive(Debug)]
pub enum BuiltinError {
UnknownCommand(String),
RedirectRead,
RedirectWrite,
CdFailed,
MkdirFailed,
CatFailed,
TouchFailed,
LsFailed,
ExportFailed,
SaveFailed,
TodoLoadFailed,
TodoSaveFailed,
TodoArgError,
TodoDataError,
RustupNotFound,
CargoNotFound,
SandboxExportFailed,
SandboxSyncFailed,
RustToolNonZeroExit {
program: String,
code: Option<i32>,
},
VmWorkspaceSyncFailed,
VmSessionError(String),
WorkspacePathOutside,
GuestFsOpFailed(String),
PipelineInterStageBufferExceeded {
limit: usize,
actual: usize,
},
}
impl std::fmt::Display for BuiltinError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::UnknownCommand(name) => write!(f, "unknown command: {name}"),
Self::RedirectRead => f.write_str("redirect read failed"),
Self::RedirectWrite => f.write_str("redirect write failed"),
Self::CdFailed => f.write_str("cd failed"),
Self::MkdirFailed => f.write_str("mkdir failed"),
Self::CatFailed => f.write_str("cat failed"),
Self::TouchFailed => f.write_str("touch failed"),
Self::LsFailed => f.write_str("ls failed"),
Self::ExportFailed => f.write_str("export failed"),
Self::SaveFailed => f.write_str("save failed"),
Self::TodoLoadFailed => f.write_str("todo load failed"),
Self::TodoSaveFailed => f.write_str("todo save failed"),
Self::TodoArgError => f.write_str("todo argument error"),
Self::TodoDataError => f.write_str("todo data error"),
Self::RustupNotFound => f.write_str("rustup not found in PATH"),
Self::CargoNotFound => f.write_str("cargo not found in PATH"),
Self::SandboxExportFailed => f.write_str("sandbox export failed"),
Self::SandboxSyncFailed => f.write_str("sandbox sync failed"),
Self::RustToolNonZeroExit { program, code } => match code {
Some(c) => write!(f, "{program} exited with status {c}"),
None => write!(f, "{program} exited with non-zero status"),
},
Self::VmWorkspaceSyncFailed => f.write_str("vm workspace sync failed"),
Self::WorkspacePathOutside => f.write_str("path outside workspace"),
Self::VmSessionError(msg) | Self::GuestFsOpFailed(msg) => write!(f, "{msg}"),
Self::PipelineInterStageBufferExceeded { limit, actual } => write!(
f,
"pipeline stage output too large ({actual} bytes; max {limit} bytes per stage)"
),
}
}
}