microsandbox_protocol/fs.rs
1//! Filesystem-related protocol message payloads.
2
3use serde::{Deserialize, Serialize};
4
5//--------------------------------------------------------------------------------------------------
6// Constants
7//--------------------------------------------------------------------------------------------------
8
9/// Maximum chunk size for streaming file data (3 MiB).
10///
11/// This stays safely under the 4 MiB frame limit after CBOR envelope overhead.
12pub const FS_CHUNK_SIZE: usize = 3 * 1024 * 1024;
13
14//--------------------------------------------------------------------------------------------------
15// Types
16//--------------------------------------------------------------------------------------------------
17
18/// A filesystem operation requested by the host.
19#[derive(Debug, Clone, Serialize, Deserialize)]
20pub enum FsOp {
21 /// Get metadata for a path.
22 Stat {
23 /// Guest path to stat.
24 path: String,
25 },
26
27 /// List directory contents.
28 List {
29 /// Guest directory path to list.
30 path: String,
31 },
32
33 /// Read a file (streaming: guest replies with FsData chunks then FsResponse).
34 Read {
35 /// Guest file path to read.
36 path: String,
37 },
38
39 /// Write a file (streaming: host sends FsData chunks, guest replies with FsResponse).
40 Write {
41 /// Guest file path to write.
42 path: String,
43 /// Permission bits to set on creation (e.g. 0o644).
44 #[serde(default)]
45 mode: Option<u32>,
46 },
47
48 /// Create a directory (and parents).
49 Mkdir {
50 /// Guest directory path to create.
51 path: String,
52 },
53
54 /// Remove a file.
55 Remove {
56 /// Guest file path to remove.
57 path: String,
58 },
59
60 /// Remove a directory recursively.
61 RemoveDir {
62 /// Guest directory path to remove.
63 path: String,
64 },
65
66 /// Copy a file or directory within the guest.
67 Copy {
68 /// Source path in guest.
69 src: String,
70 /// Destination path in guest.
71 dst: String,
72 },
73
74 /// Rename/move a file or directory.
75 Rename {
76 /// Source path in guest.
77 src: String,
78 /// Destination path in guest.
79 dst: String,
80 },
81}
82
83/// Request to perform a filesystem operation in the guest.
84#[derive(Debug, Clone, Serialize, Deserialize)]
85pub struct FsRequest {
86 /// The operation to perform.
87 pub op: FsOp,
88}
89
90/// Metadata about a filesystem entry (wire format).
91#[derive(Debug, Clone, Serialize, Deserialize)]
92pub struct FsEntryInfo {
93 /// Path of the entry.
94 pub path: String,
95
96 /// Kind of entry: `"file"`, `"dir"`, `"symlink"`, or `"other"`.
97 pub kind: String,
98
99 /// Size in bytes.
100 pub size: u64,
101
102 /// Unix permission bits.
103 pub mode: u32,
104
105 /// Last modification time as Unix timestamp (seconds since epoch).
106 pub modified: Option<i64>,
107}
108
109/// Data variants that can be included in a filesystem response.
110#[derive(Debug, Clone, Serialize, Deserialize)]
111pub enum FsResponseData {
112 /// Stat result.
113 Stat(FsEntryInfo),
114
115 /// Directory listing result.
116 List(Vec<FsEntryInfo>),
117}
118
119/// Terminal response for a filesystem operation.
120///
121/// This is always the last message sent for a given correlation ID.
122/// For streaming reads, it follows the `FsData` chunks.
123/// For simple operations, it carries the result directly.
124#[derive(Debug, Clone, Serialize, Deserialize)]
125pub struct FsResponse {
126 /// Whether the operation succeeded.
127 pub ok: bool,
128
129 /// Error message if `ok` is false.
130 #[serde(default)]
131 pub error: Option<String>,
132
133 /// Optional result data (for stat/list operations).
134 #[serde(default)]
135 pub data: Option<FsResponseData>,
136}
137
138/// A chunk of file data for streaming read/write operations.
139///
140/// An empty `data` field signals EOF (like `ExecStdin` with empty data).
141#[derive(Debug, Serialize, Deserialize)]
142pub struct FsData {
143 /// The raw file data.
144 #[serde(with = "serde_bytes")]
145 pub data: Vec<u8>,
146}