fuse/request/
macros.rs
1macro_rules! fuse_operations {
6 ($( $opcode:ident $name:ident $($arg_name:ident : $arg_type:tt)* ; )*) => {
7 pub enum FuseOperation {
9 Invalid,
12 $(
13 $name {
14 $($arg_name: fuse_operations!(@to_type $arg_type),)*
15 },
16 )*
17 }
18
19 impl FuseOperation {
20 pub fn read(opcode: u32, mut reader: impl RequestReader) -> lx::Result<Self> {
23 let op = match opcode {
24 $($opcode => {
25 $(
26 let $arg_name: fuse_operations!(@to_type $arg_type) = fuse_operations!(@to_read reader $arg_type);
27 )*
28 Self::$name {
29 $(
30 $arg_name,
31 )*
32 }
33 },)*
34 _ => {
35 tracing::error!(opcode, "Invalid opcode");
36 return Err(lx::Error::EINVAL)
37 }
38 };
39
40 Ok(op)
41 }
42 }
43
44 impl std::fmt::Debug for FuseOperation {
45 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
46 match self {
47 FuseOperation::Invalid => f.write_str("Invalid"),
48 $(
49 FuseOperation::$name { $($arg_name,)* } => {
50 let mut d = f.debug_struct(stringify!($name));
51 $(
52 fuse_operations!(@to_debug d $arg_name $arg_type);
53 )*
54 d.finish()
55 }
56 )*
57 }
58 }
59 }
60 };
61
62 (@to_type name) => { lx::LxString };
64 (@to_type str) => { lx::LxString };
65 (@to_type [u8; $arg:ident.$field:ident]) => { Box<[u8]> };
66 (@to_type [u8]) => { Box<[u8]> };
67 (@to_type $t:tt) => { $t };
68
69 (@to_read $name:ident name) => { $name.name()? };
71 (@to_read $name:ident str) => { $name.string()? };
72 (@to_read $name:ident [u8]) => { $name.read_all()? };
73 (@to_read $name:ident [u8; $arg:ident.$field:ident]) => { $name.read_count($arg.$field as usize)? };
74 (@to_read $name:ident $t:tt) => { $name.read_type()? };
75
76 (@to_debug $debug:ident $name:ident [u8]) => { $debug.field(stringify!($name), &$name.len()) };
77 (@to_debug $debug:ident $name:ident [u8; $arg:ident.$field:ident]) => { $debug.field(stringify!($name), &$name.len()) };
78 (@to_debug $debug:ident $name:ident $t:tt) => { $debug.field(stringify!($name), $name); };
79}