stomp_parser/model/frames/
sender.rs1macro_rules! sender_frame {
2 ( $name:ident, $($comment:literal,)? $command:ident, $origin:ident $(, $header_name:ident : $header_type:ident )* $(,( $( $opt_header_name:ident : $opt_header_type:ident $(: $opt_header_default:tt $(: $opt_header_default_comment:literal)?)? ),* ))? $(,[custom: $has_custom:ident])? $(,[body: $has_body:ident])? $(,$long_comment:literal)*) => {
3
4 paste::paste! {
5 $(#[doc = ""$comment]
6 #[doc = ""])?
7 #[doc = "This frame has required headers "$("`"$header_name"`")","* $(" and optional headers " $("`"$opt_header_name"`")","* )?"."]
8 $(#[doc = ""]
9 #[doc = ""$long_comment])?
10 pub struct [<$name Builder>] {
11 $(
12 $header_name: <[<$header_type Value>]<'static> as HeaderValue>::OwnedValue,
13 )*
14 $($(
15 $opt_header_name: Option<<[<$opt_header_type Value>]<'static> as HeaderValue>::OwnedValue>,
16 )*)?
17 $(
18 #[doc(hidden)]
19 #[doc = "Useless doc: `"$has_custom"`."]
20 custom: Vec<(String, String)>,
21 )?
22 $(
23 #[doc(hidden)]
24 #[doc = "Useless doc: `"$has_body"`."]
25 body: Option<Vec<u8>>,
26 )?
27 }
28
29 impl [<$name Builder>] {
30 $($(
31 #[doc = "The value of the `"$opt_header_name"` header."]
32 $($(#[doc = "Defaults to `"$opt_header_default_comment"` if not supplied."])?)?
33 pub fn $opt_header_name(mut self, new_val: <[<$opt_header_type Value>] as HeaderValue>::OwnedValue) -> [<$name Builder>] {
34 self.$opt_header_name = Some(new_val);
35
36 self
37 }
38 )*)?
39 $(
40 #[doc = "Useless doc: `"$has_custom"`."]
41 pub fn add_custom_header(mut self, name: String, value: String) -> [<$name Builder>] {
42 self.custom.push((name, value));
43 self
44 }
45 )?
46 $(
47 #[doc = "Useless doc: `"$has_body"`."]
48 pub fn body(mut self, new_value: Vec<u8>) -> [<$name Builder>] {
49 self.body = Some(new_value);
50 self
51 }
52 )?
53
54 pub fn new($(
55 $header_name: <[<$header_type Value>]<'static> as HeaderValue>::OwnedValue,
56 )*) -> [<$name Builder>] {
57 [<$name Builder>] {
58 $(
59 $header_name,
60 )*
61 $($(
62 $opt_header_name: choose_from_presence!($($opt_header_default)? {Some($($opt_header_default)?().into())},{None}),
63 )*)?
64 $(
65 custom: choose_from_presence!($has_custom {Vec::new()}, {Vec::new()}),
66 )?
67 $(
68 body: choose_from_presence!($has_body None, None),
69 )?
70 }
71 }
72
73 #[allow(unused_mut)]
74 pub fn build(mut self) -> $name<'static> {
75 let mut bytes : Vec<u8> = Vec::with_capacity(1000);
77 let bytes_ref = &mut bytes;
78
79 let mut frame = $name::init(Vec::new());
80
81 write_command(bytes_ref, $name::NAME);
82
83 $(
84 let (_,[<$header_name _range>]) = if [<$header_type Value>]::OWNED {
86 let mut bytes = self.[<$header_name>].to_string().into_bytes();
89 frame.$header_name = [<$header_type Value>]::from_owned(self.[<$header_name>]);
90 write_header(bytes_ref, [<$header_type Value>]::NAME, &mut bytes)
91 } else {
92 let mut bytes = self.[<$header_name>].to_string().into_bytes();
94 write_header(bytes_ref, [<$header_type Value>]::NAME, &mut bytes)
95 };
96 )*
97
98 $($(
99 let [<$opt_header_name _range>] = if [<$opt_header_type Value>]::OWNED {
101 self.[<$opt_header_name>].take().map(|value| {
104 let mut bytes = value.to_string().into_bytes();
105 choose_from_presence!($($opt_header_default)? {
106 frame.$opt_header_name = [<$opt_header_type Value>]::from_owned(value);
107 }, {
108 frame.$opt_header_name = Some([<$opt_header_type Value>]::from_owned(value));
109 });
110 write_header(bytes_ref, [<$opt_header_type Value>]::NAME, &mut bytes)
111 })
112 } else {
113 self.[<$opt_header_name>].take().map(|value| {
115 let mut bytes = value.to_string().into_bytes();
116 write_header(bytes_ref, [<$opt_header_type Value>]::NAME, &mut bytes)
117 })
118 };
119 )*)?
120
121 $(
122 let $has_custom : Vec<((usize, usize),(usize,usize))> = self.custom.iter().map(|(name, value)| {
123 let mut bytes = value.to_string().into_bytes();
124 write_header(bytes_ref, &name, &mut bytes)
125 }).collect();
126 )?
127
128 write_headers_end(bytes_ref);
130
131 $(
132 let mut [<_ $has_body>] = ();
133
134 let body_range = self.body.take().as_mut().map(|body| write_body(bytes_ref, body));
135 )?
136
137 write_frame_end(bytes_ref);
139
140 let ptr : *const [u8] = bytes.as_slice();
141 let slice = unsafe { ptr.as_ref().unwrap() };
142
143 frame.raw = bytes;
144
145 $(
146 if ![<$header_type Value>]::OWNED {
147 let value = unsafe { std::str::from_utf8_unchecked(&slice[[<$header_name _range>].0..[<$header_name _range>].1]) };
148 frame.$header_name = [<$header_type Value>]::from_str(value).expect("Should never fail because string valued");
149 }
150 )*
151
152 $($(
153 if let Some((_,[<$opt_header_name _range>])) = [<$opt_header_name _range>] {
154 if ![<$opt_header_type Value>]::OWNED {
155 let value = unsafe { std::str::from_utf8_unchecked(&slice[[<$opt_header_name _range>].0..[<$opt_header_name _range>].1]) };
156 choose_from_presence!($($opt_header_default)? {
157 frame.$opt_header_name = [<$opt_header_type Value>]::from_str(value).expect("Should never fail because string valued");
158 }, {
159 frame.$opt_header_name = Some([<$opt_header_type Value>]::from_str(value).expect("Should never fail because string valued"));
160 });
161 }
162 };
163 )*)?
164
165 $(
166 frame.custom = $has_custom.iter().map(|ranges| {
167 let name = unsafe { std::str::from_utf8_unchecked(&slice[ranges.0.0..ranges.0.1]) };
168 let value = unsafe { std::str::from_utf8_unchecked(&slice[ranges.1.0..ranges.1.1]) };
169
170 CustomValue::new(name, value)
171 }).collect();
172 )?
173
174
175 $(
176 [<_ $has_body>] = ();
177 body_range.iter().for_each(|body_range|{
178 frame.body = &slice[body_range.0..body_range.1]
179 });
180
181 )?
182
183 frame
184 }
185 }
186 }
187 }
188}