1use nuts_backend::Backend;
24use serde::{Deserialize, Serialize};
25use std::collections::HashMap;
26use std::fmt;
27
28macro_rules! as_into_impls {
29 ($as_name:ident + $into_name:ident => $variant:ident) => {
30 pub fn $as_name(&self) -> Option<()> {
31 match self {
32 Self::$variant => Some(()),
33 _ => None,
34 }
35 }
36
37 pub fn $into_name(self) -> Option<()> {
38 match self {
39 Self::$variant => Some(()),
40 _ => None,
41 }
42 }
43 };
44
45 ($as_name:ident + $into_name:ident => $variant:ident ( $arg:ident : $type:ty )) => {
46 pub fn $as_name(&self) -> Option<&$type> {
47 match self {
48 Self::$variant($arg) => Some($arg),
49 _ => None,
50 }
51 }
52
53 pub fn $into_name(self) -> Option<$type> {
54 match self {
55 Self::$variant($arg) => Some($arg),
56 _ => None,
57 }
58 }
59 };
60
61 ($as_name:ident + $into_name:ident => $variant:ident ( $( $arg:ident : $type:ty ),+ )) => {
62 pub fn $as_name(&self) -> Option<( $( &$type ),+)> {
63 match self {
64 Self::$variant($( $arg ),+) => Some(($( $arg ),+)),
65 _ => None,
66 }
67 }
68
69 pub fn $into_name(self) -> Option<( $( $type ),+)> {
70 match self {
71 Self::$variant($( $arg ),+) => Some(($( $arg ),+)),
72 _ => None,
73 }
74 }
75 };
76}
77
78struct VecDebug<'a>(&'a Vec<u8>);
79
80#[cfg(feature = "debug-condensed")]
81impl<'a> fmt::Debug for VecDebug<'a> {
82 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
83 write!(fmt, "<{} bytes>", self.0.len())
84 }
85}
86
87#[cfg(not(feature = "debug-condensed"))]
88impl<'a> fmt::Debug for VecDebug<'a> {
89 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
90 fmt::Debug::fmt(self.0, fmt)
91 }
92}
93
94#[derive(Deserialize, Serialize)]
96#[serde(tag = "op", content = "args", rename_all = "kebab-case")]
97pub enum Request {
98 PluginInfo,
102
103 Settings,
107
108 IdSize,
112
113 BlockSize,
117
118 IdToBytes(String),
123
124 IdToString(Vec<u8>),
129
130 Open(Vec<u8>),
135
136 Create(Vec<u8>, bool),
142
143 Info,
147
148 Aquire(Vec<u8>),
153
154 Release(Vec<u8>),
159
160 ReadHeader,
164
165 WriteHeader(Vec<u8>),
170
171 Read(Vec<u8>),
176
177 Write(Vec<u8>, Vec<u8>),
183
184 Delete,
188
189 Quit,
193}
194
195impl Request {
196 as_into_impls!(as_plugin_info + into_plugin_info => PluginInfo);
197 as_into_impls!(as_settings + into_settings => Settings);
198 as_into_impls!(as_id_size + into_id_size => IdSize);
199 as_into_impls!(as_block_size + into_block_size => BlockSize);
200 as_into_impls!(as_id_to_bytes + into_id_to_bytes => IdToBytes(arg1: String));
201 as_into_impls!(as_id_to_string + into_id_to_string => IdToString(arg1: Vec<u8>));
202 as_into_impls!(as_open + into_open => Open (arg1: Vec<u8>));
203 as_into_impls!(as_create + into_create => Create (arg1: Vec<u8>, args: bool));
204 as_into_impls!(as_info + into_info => Info);
205 as_into_impls!(as_aquire + into_aquire => Aquire (arg1: Vec<u8>));
206 as_into_impls!(as_release + into_release => Release (arg1: Vec<u8>));
207 as_into_impls!(as_read_header + into_read_header => ReadHeader);
208 as_into_impls!(as_write_header + into_write_header => WriteHeader (arg1: Vec<u8>));
209 as_into_impls!(as_read + into_read => Read (arg1: Vec<u8>));
210 as_into_impls!(as_write + into_write => Write (arg1: Vec<u8>, arg2: Vec<u8>));
211 as_into_impls!(as_delete + into_delete => Delete);
212 as_into_impls!(as_quit + into_quit => Quit);
213}
214
215impl fmt::Debug for Request {
216 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
217 match self {
218 Self::PluginInfo => write!(fmt, "PluginInfo"),
219 Self::Settings => write!(fmt, "Settings"),
220 Self::IdSize => write!(fmt, "IdSize"),
221 Self::BlockSize => write!(fmt, "BlockSize"),
222 Self::IdToBytes(arg) => fmt.debug_tuple("IdToBytes").field(arg).finish(),
223 Self::IdToString(arg) => fmt.debug_tuple("IdToString").field(&VecDebug(arg)).finish(),
224 Self::Open(arg) => fmt.debug_tuple("Open").field(&VecDebug(arg)).finish(),
225 Self::Create(arg1, arg2) => fmt
226 .debug_tuple("Create")
227 .field(&VecDebug(arg1))
228 .field(arg2)
229 .finish(),
230 Self::Info => write!(fmt, "Info"),
231 Self::Aquire(arg) => fmt.debug_tuple("Aquire").field(&VecDebug(arg)).finish(),
232 Self::Release(arg) => fmt.debug_tuple("Release").field(&VecDebug(arg)).finish(),
233 Self::ReadHeader => write!(fmt, "ReadHeader"),
234 Self::WriteHeader(arg) => fmt
235 .debug_tuple("WriteHeader")
236 .field(&VecDebug(arg))
237 .finish(),
238 Self::Read(arg) => fmt.debug_tuple("Read").field(&VecDebug(arg)).finish(),
239 Self::Write(arg1, arg2) => fmt
240 .debug_tuple("Write")
241 .field(&VecDebug(arg1))
242 .field(&VecDebug(arg2))
243 .finish(),
244 Self::Delete => write!(fmt, "Delete"),
245 Self::Quit => write!(fmt, "Quit"),
246 }
247 }
248}
249
250#[derive(Debug, Deserialize, Serialize)]
252#[serde(tag = "code", content = "args", rename_all = "kebab-case")]
253pub enum Response {
254 Ok(OkResponse),
256
257 Err(ErrorResponse),
259}
260
261impl Response {
262 pub fn ok_void() -> Response {
264 Self::Ok(OkResponse::Void)
265 }
266
267 pub fn ok_u32(value: u32) -> Response {
269 Self::Ok(OkResponse::U32(value))
270 }
271
272 pub fn ok_usize(value: usize) -> Response {
274 Self::Ok(OkResponse::Usize(value))
275 }
276
277 pub fn ok_bytes(value: Vec<u8>) -> Response {
279 Self::Ok(OkResponse::Bytes(value))
280 }
281
282 pub fn ok_string(value: String) -> Response {
284 Self::Ok(OkResponse::String(value))
285 }
286
287 pub fn ok_map(value: HashMap<String, String>) -> Response {
289 Self::Ok(OkResponse::Map(value))
290 }
291
292 pub fn err_not_applicable() -> Response {
295 Self::Err(ErrorResponse::NotApplicable)
296 }
297
298 pub fn err_message<M: AsRef<str>>(msg: M) -> Response {
300 Self::Err(ErrorResponse::Message(msg.as_ref().to_string()))
301 }
302
303 as_into_impls!(as_ok + into_ok => Ok (ok: OkResponse));
304 as_into_impls!(as_error + into_error => Err (err: ErrorResponse));
305}
306
307#[derive(Deserialize, Serialize)]
311#[serde(tag = "type", content = "args", rename_all = "kebab-case")]
312pub enum OkResponse {
313 Void,
315
316 U32(u32),
318
319 Usize(usize),
321
322 Bytes(Vec<u8>),
324
325 String(String),
327
328 Map(HashMap<String, String>),
330}
331
332impl fmt::Debug for OkResponse {
333 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
334 match self {
335 Self::Void => write!(fmt, "Void"),
336 Self::U32(arg) => fmt.debug_tuple("U32").field(arg).finish(),
337 Self::Usize(arg) => fmt.debug_tuple("Usize").field(arg).finish(),
338 Self::Bytes(arg) => fmt.debug_tuple("Bytes").field(&VecDebug(arg)).finish(),
339 Self::String(arg) => fmt.debug_tuple("String").field(arg).finish(),
340 Self::Map(arg) => fmt.debug_tuple("Map").field(arg).finish(),
341 }
342 }
343}
344
345#[derive(Debug, Deserialize, Serialize)]
347#[serde(tag = "code", content = "args", rename_all = "kebab-case")]
348pub enum ErrorResponse {
349 NotApplicable,
354
355 InvalidId,
357
358 InvalidIdData,
360
361 InvalidSettingsData,
363
364 InvalidInfo,
366
367 InvalidHeaderBytes,
369
370 Backend(String),
372
373 Message(String),
375}
376
377impl ErrorResponse {
378 pub fn message<T: AsRef<str>>(msg: T) -> ErrorResponse {
379 Self::Message(msg.as_ref().to_string())
380 }
381
382 pub fn backend<B: Backend>(err: B::Err) -> ErrorResponse {
383 Self::Backend(err.to_string())
384 }
385}
386
387impl fmt::Display for ErrorResponse {
388 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
389 match self {
390 Self::NotApplicable => write!(fmt, "the call is not applicable"),
391 Self::InvalidId => write!(fmt, "could not parse id"),
392 Self::InvalidIdData => write!(fmt, "could not create id"),
393 Self::InvalidSettingsData => write!(fmt, "could not create settings"),
394 Self::InvalidInfo => write!(fmt, "could not collect backend information"),
395 Self::InvalidHeaderBytes => write!(fmt, "invalid header bytes"),
396 Self::Backend(msg) => write!(fmt, "the backend created an error: {}", msg),
397 Self::Message(msg) => write!(fmt, "{}", msg),
398 }
399 }
400}