#![warn(missing_docs)]
pub const PROTOCOL_VERSION: &str = "0.1.0";
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[non_exhaustive]
pub enum HostCommand {
Init {
step_budget: u64,
#[serde(default)]
allowed_hosts: Vec<String>,
},
Run {
input: String,
},
StartRun {
input: String,
},
PollRun,
Signal {
signal: String,
},
Cancel,
Mount {
path: String,
},
ReadFile {
path: String,
},
WriteFile {
path: String,
data: Vec<u8>,
},
ListDir {
path: String,
},
}
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[non_exhaustive]
pub enum WorkerEvent {
Stdout(Vec<u8>),
Stderr(Vec<u8>),
Exit(i32),
Yielded,
Diagnostic(DiagnosticLevel, String),
FsChanged(String),
Version(String),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[non_exhaustive]
pub enum DiagnosticLevel {
Info,
Warning,
Error,
Trace,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn protocol_version() {
assert!(!PROTOCOL_VERSION.is_empty());
}
#[test]
fn host_command_variants() {
let cmd = HostCommand::Run {
input: "echo hello".into(),
};
assert!(matches!(cmd, HostCommand::Run { .. }));
let cmd = HostCommand::StartRun {
input: "echo hello".into(),
};
assert!(matches!(cmd, HostCommand::StartRun { .. }));
let cmd = HostCommand::Signal {
signal: "TERM".into(),
};
assert!(matches!(cmd, HostCommand::Signal { .. }));
assert_eq!(HostCommand::PollRun, HostCommand::PollRun);
}
#[test]
fn worker_event_variants() {
let evt = WorkerEvent::Exit(0);
assert_eq!(evt, WorkerEvent::Exit(0));
assert_eq!(WorkerEvent::Yielded, WorkerEvent::Yielded);
let evt = WorkerEvent::Diagnostic(DiagnosticLevel::Warning, "test".into());
assert!(matches!(
evt,
WorkerEvent::Diagnostic(DiagnosticLevel::Warning, _)
));
}
#[test]
fn progressive_commands_roundtrip_json() {
let start = HostCommand::StartRun {
input: "echo hello".into(),
};
let encoded = serde_json::to_string(&start).unwrap();
assert_eq!(encoded, r#"{"StartRun":{"input":"echo hello"}}"#);
let decoded: HostCommand = serde_json::from_str(&encoded).unwrap();
assert_eq!(decoded, start);
let encoded = serde_json::to_string(&HostCommand::PollRun).unwrap();
assert_eq!(encoded, r#""PollRun""#);
let decoded: HostCommand = serde_json::from_str(&encoded).unwrap();
assert_eq!(decoded, HostCommand::PollRun);
let signal = HostCommand::Signal {
signal: "TERM".into(),
};
let encoded = serde_json::to_string(&signal).unwrap();
assert_eq!(encoded, r#"{"Signal":{"signal":"TERM"}}"#);
let decoded: HostCommand = serde_json::from_str(&encoded).unwrap();
assert_eq!(decoded, signal);
}
#[test]
fn yielded_event_roundtrips_json() {
let encoded = serde_json::to_string(&WorkerEvent::Yielded).unwrap();
assert_eq!(encoded, r#""Yielded""#);
let decoded: WorkerEvent = serde_json::from_str(&encoded).unwrap();
assert_eq!(decoded, WorkerEvent::Yielded);
}
}