arcbox_virtio_fs/
request.rs1#[derive(Debug)]
5pub struct FuseRequest<'a> {
6 data: &'a [u8],
8}
9
10impl<'a> FuseRequest<'a> {
11 #[must_use]
13 pub const fn new(data: &'a [u8]) -> Self {
14 Self { data }
15 }
16
17 #[must_use]
19 pub const fn data(&self) -> &[u8] {
20 self.data
21 }
22
23 #[must_use]
25 pub const fn len(&self) -> usize {
26 self.data.len()
27 }
28
29 #[must_use]
31 pub const fn is_empty(&self) -> bool {
32 self.data.is_empty()
33 }
34
35 #[must_use]
39 pub fn opcode(&self) -> Option<u32> {
40 if self.data.len() < 8 {
41 return None;
42 }
43 Some(u32::from_le_bytes([
44 self.data[4],
45 self.data[5],
46 self.data[6],
47 self.data[7],
48 ]))
49 }
50
51 #[must_use]
53 pub fn unique(&self) -> Option<u64> {
54 if self.data.len() < 16 {
55 return None;
56 }
57 Some(u64::from_le_bytes([
58 self.data[8],
59 self.data[9],
60 self.data[10],
61 self.data[11],
62 self.data[12],
63 self.data[13],
64 self.data[14],
65 self.data[15],
66 ]))
67 }
68}
69
70#[derive(Debug)]
72pub struct FuseResponse {
73 data: Vec<u8>,
75}
76
77impl FuseResponse {
78 #[must_use]
80 pub fn new(unique: u64, payload: Vec<u8>) -> Self {
81 let len = (16 + payload.len()) as u32;
82 let mut data = Vec::with_capacity(len as usize);
83
84 data.extend_from_slice(&len.to_le_bytes());
86 data.extend_from_slice(&0i32.to_le_bytes()); data.extend_from_slice(&unique.to_le_bytes());
88
89 data.extend_from_slice(&payload);
90
91 Self { data }
92 }
93
94 #[must_use]
96 pub fn error(unique: u64, errno: i32) -> Self {
97 let len = 16u32;
98 let mut data = Vec::with_capacity(len as usize);
99
100 data.extend_from_slice(&len.to_le_bytes());
101 data.extend_from_slice(&(-errno).to_le_bytes());
102 data.extend_from_slice(&unique.to_le_bytes());
103
104 Self { data }
105 }
106
107 #[must_use]
109 pub fn data(&self) -> &[u8] {
110 &self.data
111 }
112
113 #[must_use]
115 pub fn into_data(self) -> Vec<u8> {
116 self.data
117 }
118}
119
120#[cfg(test)]
121mod tests {
122 use super::*;
123
124 #[test]
125 fn test_fuse_request_new() {
126 let data = vec![0u8; 64];
127 let request = FuseRequest::new(&data);
128 assert_eq!(request.len(), 64);
129 assert!(!request.is_empty());
130 }
131
132 #[test]
133 fn test_fuse_request_empty() {
134 let data = vec![];
135 let request = FuseRequest::new(&data);
136 assert!(request.is_empty());
137 }
138
139 #[test]
140 fn test_fuse_request_opcode() {
141 let mut data = vec![0u8; 16];
142 data[4..8].copy_from_slice(&42u32.to_le_bytes());
143
144 let request = FuseRequest::new(&data);
145 assert_eq!(request.opcode(), Some(42));
146 }
147
148 #[test]
149 fn test_fuse_request_opcode_too_small() {
150 let data = vec![0u8; 4];
151 let request = FuseRequest::new(&data);
152 assert!(request.opcode().is_none());
153 }
154
155 #[test]
156 fn test_fuse_request_unique() {
157 let mut data = vec![0u8; 16];
158 data[8..16].copy_from_slice(&12345u64.to_le_bytes());
159
160 let request = FuseRequest::new(&data);
161 assert_eq!(request.unique(), Some(12345));
162 }
163
164 #[test]
165 fn test_fuse_response_new() {
166 let response = FuseResponse::new(123, vec![1, 2, 3, 4]);
167
168 let data = response.data();
169 assert_eq!(data.len(), 20); let len = u32::from_le_bytes([data[0], data[1], data[2], data[3]]);
172 let error = i32::from_le_bytes([data[4], data[5], data[6], data[7]]);
173 let unique = u64::from_le_bytes([
174 data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15],
175 ]);
176
177 assert_eq!(len, 20);
178 assert_eq!(error, 0);
179 assert_eq!(unique, 123);
180 assert_eq!(&data[16..], &[1, 2, 3, 4]);
181 }
182
183 #[test]
184 fn test_fuse_response_error() {
185 let response = FuseResponse::error(456, libc::ENOENT);
186
187 let data = response.data();
188 assert_eq!(data.len(), 16);
189
190 let len = u32::from_le_bytes([data[0], data[1], data[2], data[3]]);
191 let error = i32::from_le_bytes([data[4], data[5], data[6], data[7]]);
192 let unique = u64::from_le_bytes([
193 data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15],
194 ]);
195
196 assert_eq!(len, 16);
197 assert_eq!(error, -libc::ENOENT);
198 assert_eq!(unique, 456);
199 }
200
201 #[test]
202 fn test_fuse_response_into_data() {
203 let response = FuseResponse::new(1, vec![]);
204 let data = response.into_data();
205 assert_eq!(data.len(), 16);
206 }
207}