wasmsh_protocol/lib.rs
1//! Message protocol for the wasmsh browser worker bridge.
2//!
3//! Defines versioned, serializable messages exchanged between the host
4//! page and the wasmsh Web Worker.
5//!
6//! ## Protocol version
7//! Current version: `0.1.0`
8
9#![warn(missing_docs)]
10
11/// Protocol version string.
12pub const PROTOCOL_VERSION: &str = "0.1.0";
13
14/// A command sent from the host to the worker.
15#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
16#[non_exhaustive]
17pub enum HostCommand {
18 /// Initialize the shell runtime with optional configuration.
19 Init {
20 /// Maximum step budget per execution (0 = unlimited).
21 step_budget: u64,
22 /// Hostnames/IPs allowed for network access (empty = no network).
23 ///
24 /// Patterns: exact host (`api.example.com`), wildcard (`*.example.com`),
25 /// IP (`192.168.1.100`), host with port (`api.example.com:8080`).
26 #[serde(default)]
27 allowed_hosts: Vec<String>,
28 },
29 /// Execute a shell command string.
30 Run {
31 /// The shell source text to execute.
32 input: String,
33 },
34 /// Cancel the currently running execution.
35 Cancel,
36 /// Mount a virtual filesystem at the given path.
37 Mount {
38 /// Absolute path at which to mount the filesystem.
39 path: String,
40 },
41 /// Read a file from the virtual filesystem.
42 ReadFile {
43 /// Absolute path of the file to read.
44 path: String,
45 },
46 /// Write data to a file in the virtual filesystem.
47 WriteFile {
48 /// Absolute path of the file to write.
49 path: String,
50 /// Raw bytes to write into the file.
51 data: Vec<u8>,
52 },
53 /// List directory contents.
54 ListDir {
55 /// Absolute path of the directory to list.
56 path: String,
57 },
58}
59
60/// An event sent from the worker to the host.
61#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
62#[non_exhaustive]
63pub enum WorkerEvent {
64 /// Shell produced stdout output.
65 Stdout(Vec<u8>),
66 /// Shell produced stderr output.
67 Stderr(Vec<u8>),
68 /// Command execution finished with exit code.
69 Exit(i32),
70 /// A diagnostic message (warning, info, trace).
71 Diagnostic(DiagnosticLevel, String),
72 /// A file in the VFS was changed.
73 FsChanged(String),
74 /// Protocol version announcement (sent on Init).
75 Version(String),
76}
77
78/// Diagnostic severity level.
79#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
80#[non_exhaustive]
81pub enum DiagnosticLevel {
82 /// Informational message.
83 Info,
84 /// Non-fatal warning.
85 Warning,
86 /// Error-level diagnostic.
87 Error,
88 /// Low-level trace output.
89 Trace,
90}
91
92#[cfg(test)]
93mod tests {
94 use super::*;
95
96 #[test]
97 fn protocol_version() {
98 assert!(!PROTOCOL_VERSION.is_empty());
99 }
100
101 #[test]
102 fn host_command_variants() {
103 let cmd = HostCommand::Run {
104 input: "echo hello".into(),
105 };
106 assert!(matches!(cmd, HostCommand::Run { .. }));
107 }
108
109 #[test]
110 fn worker_event_variants() {
111 let evt = WorkerEvent::Exit(0);
112 assert_eq!(evt, WorkerEvent::Exit(0));
113
114 let evt = WorkerEvent::Diagnostic(DiagnosticLevel::Warning, "test".into());
115 assert!(matches!(
116 evt,
117 WorkerEvent::Diagnostic(DiagnosticLevel::Warning, _)
118 ));
119 }
120}