Skip to main content

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}