votable/
macros.rs

1macro_rules! impl_builder_mandatory_string_attr {
2  ($arg:ident) => {
3    paste! {
4      #[doc = concat!("Re-set the mandatory attribute `", stringify!($arg), "` taking the ownership and returning itself.")]
5      pub fn [<set_ $arg>]<I: Into<String>>(mut self, $arg: I) -> Self {
6        self.[<set_ $arg _by_ref>]($arg);
7        self
8      }
9      #[doc = concat!("Re-set the mandatory attribute `", stringify!($arg), "` by mutable ref.")]
10      pub fn [<set_ $arg _by_ref>]<I: Into<String>>(&mut self, $arg: I) {
11        self.$arg = $arg.into();
12      }
13    }
14  };
15  ($arg:ident, $alt:ident) => {
16    paste! {
17      #[doc = concat!("Re-set the mandatory attribute `", stringify!($arg), "` taking the ownership and returning itself.")]
18      pub fn [<set_ $alt>]<I: Into<String>>(mut self, $arg: I) -> Self {
19        self.[<set_ $alt _by_ref>]($arg);
20        self
21      }
22      #[doc = concat!("Re-set the mandatory attribute `", stringify!($arg), "` by mutable ref.")]
23      pub fn [<set_ $alt _by_ref>]<I: Into<String>>(&mut self, $arg: I) {
24        self.$arg = $arg.into();
25      }
26    }
27  };
28}
29
30macro_rules! impl_builder_mandatory_string_attr_delegated {
31  ($arg:ident, $del:ident) => {
32    paste! {
33      #[doc = concat!("Re-set the mandatory attribute `", stringify!($arg), "` taking the ownership and returning itself.")]
34      pub fn [<set_ $arg>]<I: Into<String>>(mut self, $arg: I) -> Self {
35        self.$del.$arg = $arg.into();
36        self
37      }
38      #[doc = concat!("Re-set the mandatory attribute `", stringify!($arg), "` by mutable ref.")]
39      pub fn [<set_ $arg _by_ref>]<I: Into<String>>(&mut self, $arg: I) {
40        self.$del.$arg = $arg.into();
41      }
42    }
43  };
44  ($arg:ident, $alt:ident, $del:ident) => {
45    paste! {
46      #[doc = concat!("Re-set the mandatory attribute `", stringify!($arg), "` taking the ownership and returning itself.")]
47      pub fn [<set_ $alt>]<I: Into<String>>(mut self, $arg: I) -> Self {
48        self.$del.$arg = $arg.into();
49        self
50      }
51      #[doc = concat!("Re-set the mandatory attribute `", stringify!($arg), "` by mutable ref.")]
52      pub fn [<set_ $alt _by_ref>]<I: Into<String>>(&mut self, $arg: I) {
53        self.$del.$arg = $arg.into();
54      }
55    }
56  };
57}
58
59macro_rules! impl_builder_mandatory_attr {
60  ($arg: ident, $t: ident) => {
61    paste! {
62      #[doc = concat!("Re-set the mandatory attribute `", stringify!($arg), "` taking the ownership and returning itself.")]
63      pub fn [<set_ $arg>](mut self, $arg: $t) -> Self {
64        self.$arg = $arg;
65        self
66      }
67      #[doc = concat!("Re-set the mandatory attribute `", stringify!($arg), "` by mutable ref.")]
68      pub fn [<set_ $arg _by_ref>](&mut self, $arg: $t) {
69        self.$arg = $arg;
70      }
71    }
72  };
73  ($arg: ident, $alt:ident, $t: ident) => {
74    paste! {
75      #[doc = concat!("Re-set the mandatory attribute `", stringify!($arg), "` taking the ownership and returning itself.")]
76      pub fn [<set_ $alt>](mut self, $arg: $t) -> Self {
77        self.$arg = $arg;
78        self
79      }
80     #[doc = concat!("Re-set the mandatory attribute `", stringify!($arg), "` by mutable ref.")]
81      pub fn [<set_ $alt _by_ref>](&mut self, $arg: $t) {
82        self.$arg = $arg;
83      }
84    }
85  };
86}
87
88macro_rules! impl_builder_mandatory_attr_delegated {
89  ($arg: ident, $t: ident, $del:ident) => {
90    paste! {
91      #[doc = concat!("Re-set the mandatory attribute `", stringify!($arg), "` taking the ownership and returning itself.")]
92      pub fn [<set_ $arg>](mut self, $arg: $t) -> Self {
93        self.$del.$arg = $arg;
94        self
95      }
96      #[doc = concat!("Re-set the mandatory attribute `", stringify!($arg), "` by mutable ref.")]
97      pub fn [<set_ $arg _by_ref>](&mut self, $arg: $t) {
98        self.$del.$arg = $arg;
99      }
100    }
101  };
102  ($arg: ident, $alt:ident, $t: ident, $del:ident) => {
103    paste! {
104      #[doc = concat!("Re-set the mandatory attribute `", stringify!($arg), "` taking the ownership and returning itself.")]
105      pub fn [<set_ $alt>](mut self, $arg: $t) -> Self {
106        self.$del.$arg = $arg;
107        self
108      }
109      #[doc = concat!("Re-set the mandatory attribute `", stringify!($arg), "` by mutable ref.")]
110      pub fn [<set_ $alt _by_ref>](&mut self, $arg: $t) {
111        self.$del.$arg = $arg;
112      }
113    }
114  };
115}
116
117/// E.g. `impl_builder_opt_string_attr(id)` leads to
118/// ```ignore
119/// pub fn set_id<I: Into<String>>(mut self, id: I) -> Self {
120///    self.id.insert(id.into());
121///    self
122/// }
123/// ```
124macro_rules! impl_builder_opt_string_attr {
125  ($arg:ident) => {
126    paste! {
127      #[doc = concat!("Set the optional attribute `", stringify!($arg), "` taking the ownership and returning itself.")]
128      pub fn [<set_ $arg>]<I: Into<String>>(mut self, $arg: I) -> Self {
129        self.$arg = Some($arg.into());
130        self
131      }
132      #[doc = concat!("Set the optional attribute `", stringify!($arg), "` by mutable ref.")]
133      pub fn [<set_ $arg _by_ref>]<I: Into<String>>(&mut self, $arg: I) {
134        self.$arg = Some($arg.into());
135      }
136    }
137  };
138  ($arg:ident, $alt:ident) => {
139    paste! {
140      #[doc = concat!("Set the optional attribute `", stringify!($arg), "` taking the ownership and returning itself.")]
141      pub fn [<set_ $alt>]<I: Into<String>>(mut self, $arg: I) -> Self {
142        self.$arg = Some($arg.into());
143        self
144      }
145      #[doc = concat!("Set the optional attribute `", stringify!($arg), "` by mutable ref.")]
146      pub fn [<set_ $alt _by_ref>]<I: Into<String>>(&mut self, $arg: I) {
147        self.$arg = Some($arg.into());
148      }
149    }
150  };
151}
152
153macro_rules! impl_builder_opt_string_attr_delegated {
154  ($arg:ident, $del:ident) => {
155    paste! {
156      #[doc = concat!("Set the optional attribute `", stringify!($arg), "` taking the ownership and returning itself.")]
157      pub fn [<set_ $arg>]<I: Into<String>>(mut self, $arg: I) -> Self {
158        self.$del.$arg = Some($arg.into());
159        self
160      }
161      #[doc = concat!("Set the optional attribute `", stringify!($arg), "` by mutable ref.")]
162      pub fn [<set_ $arg _by_ref>]<I: Into<String>>(&mut self, $arg: I) {
163        self.$del.$arg = Some($arg.into());
164      }
165    }
166  };
167  ($arg:ident, $alt:ident, $del:ident) => {
168    paste! {
169      #[doc = concat!("Set the optional attribute `", stringify!($arg), "` taking the ownership and returning itself.")]
170      pub fn [<set_ $alt>]<I: Into<String>>(mut self, $arg: I) -> Self {
171        self.$del.$arg = Some($arg.into());
172        self
173      }
174      #[doc = concat!("Set the optional attribute `", stringify!($arg), "` by mutable ref.")]
175      pub fn [<set_ $alt _by_ref>]<I: Into<String>>(&mut self, $arg: I) {
176        self.$del.$arg = Some($arg.into());
177      }
178    }
179  };
180}
181
182/// E.g. `impl_builder_opt_attr(description, Description)` leads to
183/// ```ignore
184/// pub fn set_description<I: Into<String>>(mut self, description: Description) -> Self {
185///    self.description.insert(description);
186///    self
187/// }
188/// ```
189macro_rules! impl_builder_opt_attr {
190  ($arg: ident, $t: ident) => {
191    paste! {
192      #[doc = concat!("Set the optional attribute `", stringify!($arg), "` taking the ownership and returning itself.")]
193      pub fn [<set_ $arg>](mut self, $arg: $t) -> Self {
194        self.$arg = Some($arg);
195        self
196      }
197      #[doc = concat!("Set the optional attribute `", stringify!($arg), "` by mutable ref.")]
198      pub fn [<set_ $arg _by_ref>](&mut self, $arg: $t) {
199        self.$arg = Some($arg);
200      }
201    }
202  };
203  ($arg: ident, $alt:ident, $t: ident) => {
204    paste! {
205      #[doc = concat!("Set the optional attribute `", stringify!($arg), "` taking the ownership and returning itself.")]
206      pub fn [<set_ $alt>](mut self, $arg: $t) -> Self {
207        self.$arg = Some($arg);
208        self
209      }
210      #[doc = concat!("Set the optional attribute `", stringify!($arg), "` by mutable ref.")]
211      pub fn [<set_ $alt _by_ref>](&mut self, $arg: $t) {
212        self.$arg = Some($arg);
213      }
214    }
215  };
216}
217
218macro_rules! impl_builder_opt_attr_delegated {
219  ($arg: ident, $t: ident, $del:ident) => {
220    paste! {
221      #[doc = concat!("Set the optional attribute `", stringify!($arg), "` taking the ownership and returning itself.")]
222      pub fn [<set_ $arg>](mut self, $arg: $t) -> Self {
223        self.[<set_ $arg _by_ref>]($arg);
224        self
225      }
226      #[doc = concat!("Set the optional attribute `", stringify!($arg), "` by mutable ref.")]
227      pub fn [<set_ $arg _by_ref>](&mut self, $arg: $t) {
228        self.$del.$arg = Some($arg);
229      }
230    }
231  };
232  ($arg: ident, $alt:ident, $t: ident, $del:ident) => {
233    paste! {
234      #[doc = concat!("Set the optional attribute `", stringify!($arg), "` taking the ownership and returning itself.")]
235      pub fn [<set_ $alt>](mut self, $arg: $t) -> Self {
236        self.[<set_ $alt _by_ref>]($arg);
237        self
238      }
239      #[doc = concat!("Set the optional attribute `", stringify!($arg), "` by mutable ref.")]
240      pub fn [<set_ $alt _by_ref>](&mut self, $arg: $t) {
241        self.$del.$arg = Some($arg);
242      }
243    }
244  };
245}
246
247macro_rules! impl_builder_opt_subelem {
248  ($arg: ident, $t: ident) => {
249    paste! {
250      #[doc = concat!("Set the optional sub-element `", stringify!($arg), "` taking the ownership and returning itself.")]
251      pub fn [<set_ $arg>](mut self, $arg: $t) -> Self {
252        self.[<set_ $arg _by_ref>]($arg);
253        self
254      }
255      #[doc = concat!("Set the optional sub-element `", stringify!($arg), "` by mutable ref.")]
256      pub fn [<set_ $arg _by_ref>](&mut self, $arg: $t) {
257        if self.$arg.replace($arg).is_some() {
258          warn!(concat!("Multiple occurrence of ", stringify!($arg), ". All but the last one are discarded."));
259        }
260      }
261      #[doc = concat!("Reset the optional sub-element `", stringify!($arg), "` taking the ownership and returning itself.")]
262      pub fn [<reset_ $arg>](mut self, $arg: $t) -> Self {
263        self.[<reset_ $arg _by_ref>]($arg);
264        self
265      }
266      #[doc = concat!("Reset the optional sub-element `", stringify!($arg), "` by mutable ref.")]
267      pub fn [<reset_ $arg _by_ref>](&mut self, $arg: $t) {
268        let _ = self.$arg.replace($arg);
269      }
270    }
271  };
272  ($arg: ident, $alt:ident, $t: ident) => {
273    paste! {
274      #[doc = concat!("Set the optional sub-element `", stringify!($arg), "` taking the ownership and returning itself.")]
275      pub fn [<set_ $alt>](mut self, $arg: $t) -> Self {
276        self.[<set_ $alt _by_ref>]($arg);
277        self
278      }
279      #[doc = concat!("Set the optional sub-element `", stringify!($arg), "` by mutable ref.")]
280      pub fn [<set_ $alt _by_ref>](&mut self, $arg: $t) {
281        if self.$arg.replace($arg).is_some() {
282          warn!(concat!("Multiple occurrence of ", stringify!($arg), ". All but the last one are discarded."));
283        }
284      }
285      #[doc = concat!("Reset the optional sub-element `", stringify!($arg), "` taking the ownership and returning itself.")]
286      pub fn [<reset_ $alt>](mut self, $arg: $t) -> Self {
287        self.[<reset_ $alt _by_ref>]($arg);
288        self
289      }
290      #[doc = concat!("Reset the optional sub-element `", stringify!($arg), "` by mutable ref.")]
291      pub fn [<reset_ $alt _by_ref>](&mut self, $arg: $t) {
292        let _ = self.$arg.replace($arg);
293      }
294    }
295  };
296}
297
298macro_rules!  impl_builder_opt_subelem_delegated {
299  ($arg: ident, $t: ident, $del:ident) => {
300    paste! {
301      #[doc = concat!("Set the optional sub-element `", stringify!($arg), "` taking the ownership and returning itself.")]
302      pub fn [<set_ $arg>](mut self, $arg: $t) -> Self {
303        self.[<set_ $arg _by_ref>]($arg);
304        self
305      }
306      #[doc = concat!("Set the optional sub-element `", stringify!($arg), "` by mutable ref.")]
307      pub fn [<set_ $arg _by_ref>](&mut self, $arg: $t) {
308        if self.$del.$arg.replace($arg).is_some() {
309          warn!(concat!("Multiple occurrence of ", stringify!($arg), ". All but the last one are discarded."));
310        }
311      }
312      #[doc = concat!("Set the optional sub-element `", stringify!($arg), "` taking the ownership and returning itself.")]
313      pub fn [<reset_ $arg>](mut self, $arg: $t) -> Self {
314        self.[<reset_ $arg _by_ref>]($arg);
315        self
316      }
317      #[doc = concat!("Set the optional sub-element `", stringify!($arg), "` by mutable ref.")]
318      pub fn [<reset_ $arg _by_ref>](&mut self, $arg: $t) {
319        let _ = self.$del.$arg.replace($arg);
320      }
321    }
322  };
323  ($arg: ident, $alt:ident, $t: ident, $del:ident) => {
324    paste! {
325      #[doc = concat!("Set the optional sub-element `", stringify!($arg), "` taking the ownership and returning itself.")]
326      pub fn [<set_ $alt>](mut self, $arg: $t) -> Self {
327        self.[<set_ $alt _by_ref>]($arg);
328        self
329      }
330      #[doc = concat!("Set the optional sub-element `", stringify!($arg), "` by mutable ref.")]
331      pub fn [<set_ $alt _by_ref>](&mut self, $arg: $t) {
332        if self.$del.$arg.replace($arg).is_some() {
333          warn!(concat!("Multiple occurrence of ", stringify!($arg), ". All but the last one are discarded."));
334        }
335      }
336      #[doc = concat!("Set the optional sub-element `", stringify!($arg), "` taking the ownership and returning itself.")]
337      pub fn [<reset_ $alt>](mut self, $arg: $t) -> Self {
338        self.[<reset_ $alt _by_ref>]($arg);
339        self
340      }
341      #[doc = concat!("Set the optional sub-element `", stringify!($arg), "` by mutable ref.")]
342      pub fn [<set_ $alt _by_ref>](&mut self, $arg: $t) {
343        let _ = self.$del.$arg.replace($arg);
344      }
345    }
346  };
347}
348
349macro_rules! impl_has_content {
350  ($tag:ident) => {
351    paste! {
352      impl HasContent for $tag {
353        fn get_content(&self) -> Option<&str> {
354          self.content.as_deref()
355        }
356        fn set_content<S: Into<String>>(mut self, content: S) -> Self {
357          self.content = Some(content.into());
358          self
359        }
360        fn set_content_by_ref<S: Into<String>>(&mut self, content: S) {
361          self.content = Some(content.into());
362        }
363      }
364    }
365  };
366}
367
368/// E.g. `impl_builder_push_elem(CooSys, ResourceElem)` leads to
369/// ```ignore
370/// pub fn push_coosys(mut self, coosys: CooSys) -> Self {
371///   self.elems.push(ResourceElem::CooSyst(coosys));
372///   self
373/// }
374/// ```
375macro_rules! impl_builder_push_elem {
376  ($t: ident, $e: expr) => {
377    paste! {
378      #[doc = concat!("Add the given `", stringify!($e), "` to the element list.")]
379      pub fn [<push_ $t:lower>](mut self, [<$t:lower>]: $t) -> Self {
380        self.[<push_ $t:lower _by_ref>]([<$t:lower>]);
381        self
382      }
383      #[doc = concat!("Add the given `", stringify!($e), "` to the element list, by mutable ref.")]
384      pub fn [<push_ $t:lower _by_ref>](&mut self, [<$t:lower>]: $t) {
385        self.elems.push($e::$t([<$t:lower>]));
386      }
387    }
388  };
389  ($t: ident, $e: expr, $a: ident) => {
390    paste! {
391      #[doc = concat!("Add the given `", stringify!($a), "` to the element list.")]
392      pub fn [<push_ $t:lower>](mut self, [<$t:lower>]: $a) -> Self {
393        self.[<push_ $t:lower _by_ref>]([<$t:lower>]);
394        self
395      }
396      #[doc = concat!("Add the given `", stringify!($a), "` to the element list, by mutable ref.")]
397      pub fn [<push_ $t:lower _by_ref>](&mut self, [<$t:lower>]: $a) {
398        self.elems.push($e::$t([<$t:lower>]));
399      }
400    }
401  };
402}
403
404/// E.g. `impl_builder_push_boxed_elem(CooSys, ResourceElem)` leads to
405/// ```ignore
406/// pub fn push_coosys(mut self, coosys: CooSys) -> Self {
407///   self.elems.push(ResourceElem::CooSyst(Box::new(coosys)));
408///   self
409/// }
410/// ```
411macro_rules! impl_builder_push_boxed_elem {
412  ($t: ident, $e: expr) => {
413    paste! {
414      #[doc = concat!("Add the given `", stringify!($e), "` to the element list.")]
415      pub fn [<push_ $t:lower>](mut self, [<$t:lower>]: $t) -> Self {
416        self.[<push_ $t:lower _by_ref>]([<$t:lower>]);
417        self
418      }
419      #[doc = concat!("Add the given `", stringify!($e), "` to the element list, by mutable ref.")]
420      pub fn [<push_ $t:lower _by_ref>](&mut self, [<$t:lower>]: $t) {
421        self.elems.push($e::$t(Box::new([<$t:lower>])));
422      }
423    }
424  };
425  ($t: ident, $e: expr, $a: ident) => {
426    paste! {
427      #[doc = concat!("Add the given `", stringify!($a), "` to the element list.")]
428      pub fn [<push_ $t:lower>](mut self, [<$t:lower>]: $a) -> Self {
429        self.[<push_ $t:lower _by_ref>]([<$t:lower>]);
430        self
431      }
432      #[doc = concat!("Add the given `", stringify!($a), "` to the element list, by mutable ref.")]
433      pub fn [<push_ $t:lower _by_ref>](&mut self, [<$t:lower>]: $a) {
434        self.elems.push($e::$t([<$t:lower>]));
435      }
436    }
437  };
438}
439
440/*
441macro_rules! impl_builder_prepend_elem {
442  ($t: ident, $e: expr) => {
443    paste! {
444      #[doc = concat!("Add the given `", stringify!($e), "` to the element list.")]
445      pub fn [<push_ $t:lower>](mut self, [<$t:lower>]: $t) -> Self {
446        self.[<push_ $t:lower _by_ref>]([<$t:lower>]);
447        self
448      }
449      #[doc = concat!("Add the given `", stringify!($e), "` to the element list, by mutable ref.")]
450      pub fn [<push_ $t:lower _by_ref>](&mut self, [<$t:lower>]: $t) {
451        self.elems.insert(0, $e::$t([<$t:lower>]));
452      }
453    }
454  };
455  ($t: ident, $e: expr, $a: ident) => {
456    paste! {
457      #[doc = concat!("Add the given `", stringify!($a), "` to the element list.")]
458      pub fn [<push_ $t:lower>](mut self, [<$t:lower>]: $a) -> Self {
459        self.[<push_ $t:lower _by_ref>]([<$t:lower>]);
460        self
461      }
462      #[doc = concat!("Add the given `", stringify!($a), "` to the element list, by mutable ref.")]
463      pub fn [<push_ $t:lower _by_ref>](&mut self, [<$t:lower>]: $a) {
464        self.elems.insert(0, $e::$t([<$t:lower>]));
465      }
466    }
467  };
468}*/
469
470/// E.g. `impl_builder_push(Info)` leads to
471/// ```ignore
472/// pub fn push_info(mut self, info: Info) -> Self {
473///   self.infos.push(info);
474///   self
475/// }
476/// ```
477macro_rules! impl_builder_push {
478  ($t: ident) => {
479    paste! {
480      #[doc = concat!("Add the given object to the list of `", stringify!($t), "`.")]
481      pub fn [<push_ $t:lower>](mut self, [<$t:lower>]: $t) -> Self {
482        self.[<push_ $t:lower _by_ref>]([<$t:lower>]);
483        self
484      }
485      #[doc = concat!("Add the given object to the list of `", stringify!($t), "`, by mutable ref.")]
486      pub fn [<push_ $t:lower _by_ref>](&mut self, [<$t:lower>]: $t) {
487        self.[<$t:lower s>].push([<$t:lower>]);
488      }
489    }
490  };
491  ($t: ident, $c: ident) => {
492    paste! {
493      #[doc = concat!("Add the given object to the list of `", stringify!($t), "`.")]
494      pub fn [<push_ $t:lower>](mut self, [<$t:lower>]: $t<$c>) -> Self {
495        self.[<push_ $t:lower _by_ref>]([<$t:lower>]);
496        self
497      }
498      #[doc = concat!("Add the given object to the list of `", stringify!($t), "`, by mutable ref.")]
499      pub fn [<push_ $t:lower _by_ref>](&mut self, [<$t:lower>]: $t<$c>) {
500        self.[<$t:lower s>].push([<$t:lower>]);
501      }
502    }
503  };
504}
505
506macro_rules! impl_builder_prepend {
507  ($t: ident) => {
508    paste! {
509      #[doc = concat!("Prepend the given object to the list of `", stringify!($t), "`.")]
510      pub fn [<prepend_ $t:lower>](mut self, [<$t:lower>]: $t) -> Self {
511        self.[<prepend_ $t:lower _by_ref>]([<$t:lower>]);
512        self
513      }
514      #[doc = concat!("Prepend the given object to the list of `", stringify!($t), "`, by mutable ref.")]
515      pub fn [<prepend_ $t:lower _by_ref>](&mut self, [<$t:lower>]: $t) {
516        self.[<$t:lower s>].insert(0, [<$t:lower>]);
517      }
518    }
519  };
520  ($t: ident, $c: ident) => {
521    paste! {
522      #[doc = concat!("Prepend the given object to the list of `", stringify!($t), "`.")]
523      pub fn [<prepend_ $t:lower>](mut self, [<$t:lower>]: $t<$c>) -> Self {
524        self.[<prepend_ $t:lower _by_ref>]([<$t:lower>]);
525        self
526      }
527      #[doc = concat!("Prepend the given object to the list of `", stringify!($t), "`, by mutable ref.")]
528      pub fn [<prepend_ $t:lower _by_ref>](&mut self, [<$t:lower>]: $t<$c>) {
529        self.[<$t:lower s>].insert(0, [<$t:lower>]);
530      }
531    }
532  };
533}
534
535macro_rules! impl_builder_push_delegated {
536  ($t: ident, $del: ident) => {
537    paste! {
538      #[doc = concat!("Add the given object to the list of `", stringify!($t), "`.")]
539      pub fn [<push_ $t:lower>](mut self, [<$t:lower>]: $t) -> Self {
540        self.[<push_ $t:lower _by_ref>]([<$t:lower>]);
541        self
542      }
543      #[doc = concat!("Add the given object to the list of `", stringify!($t), "`, by mutable ref.")]
544      pub fn [<push_ $t:lower _by_ref>](&mut self, [<$t:lower>]: $t) {
545        self.$del.[<$t:lower s>].push([<$t:lower>]);
546      }
547    }
548  };
549  ($t: ident, $c: ident, $del: ident) => {
550    paste! {
551      #[doc = concat!("Add the given object to the list of `", stringify!($t), "`.")]
552      pub fn [<push_ $t:lower>](mut self, [<$t:lower>]: $t<$c>) -> Self {
553        self.[<push_ $t:lower _by_ref>]([<$t:lower>]);
554        self
555      }
556      #[doc = concat!("Add the given object to the list of `", stringify!($t), "`, by mutable ref.")]
557      pub fn [<push_ $t:lower _by_ref>](&mut self, [<$t:lower>]: $t<$c>) {
558        self.$del.[<$t:lower s>].push([<$t:lower>]);
559      }
560    }
561  };
562}
563
564/// Like macro `impl_builder_push` but without adding a 's' to the vector attribute name.
565#[cfg(feature = "mivot")]
566macro_rules! impl_builder_push_no_s {
567  ($t: ident) => {
568    paste! {
569      #[doc = concat!("Add the given object to the list of `", stringify!($t), "`.")]
570      pub fn [<push_ $t:lower>](mut self, [<$t:lower>]: $t) -> Self {
571        self.[<$t:lower>].push([<$t:lower>]);
572        self
573      }
574      #[doc = concat!("Add the given object to the list of `", stringify!($t), "`, by mutable ref.")]
575      pub fn [<push_ $t:lower _by_ref>](&mut self, [<$t:lower>]: $t) {
576        self.[<$t:lower>].push([<$t:lower>]);
577      }
578    }
579  };
580  ($t: ident, $c: ident) => {
581    paste! {
582      #[doc = concat!("Add the given object to the list of `", stringify!($t), "`.")]
583      pub fn [<push_ $t:lower>](mut self, [<$t:lower>]: $t<$c>) -> Self {
584        self.[<$t:lower>].push([<$t:lower>]);
585        self
586      }
587      #[doc = concat!("Add the given object to the list of `", stringify!($t), "`, by mutable ref.")]
588      pub fn [<push_ $t:lower _by_ref>](&mut self, [<$t:lower>]: $t<$c>) {
589        self.[<$t:lower>].push([<$t:lower>]);
590      }
591    }
592  };
593}
594
595/// Simply append the following method:
596/// ```ignore
597/// pub fn push_post_info(mut self, info: Info) -> Self {
598///   self.post_infos.push(info);
599///   self
600/// }
601/// ```
602macro_rules! impl_builder_push_post_info {
603  () => {
604    #[doc = concat!("Add the given info to the list of post infos.")]
605    pub fn push_post_info(mut self, info: Info) -> Self {
606      self.push_post_info_by_ref(info);
607      self
608    }
609    #[doc = concat!("Add the given info to the list of post infos, by mutable ref.")]
610    pub fn push_post_info_by_ref(&mut self, info: Info) {
611      self.post_infos.push(info);
612    }
613  };
614}
615
616/// Simply append the following method:
617/// ```ignore
618/// pub fn insert_extra<S: Into<String>>(mut self, key: S, value: Value) -> Self {
619///   self.extra.insert(key.into(), value);
620///   self
621/// }
622/// ```
623macro_rules! impl_builder_insert_extra {
624  () => {
625    /// Insert a **non-standard** attribute, taking the ownership and returning itself.
626    /// # Info
627    /// The attribute name must contains ':', else the  `extra:` prefix is added.
628    pub fn insert_extra<S: Into<String>>(mut self, key: S, value: Value) -> Self {
629      self.insert_extra_by_ref(key, value);
630      self
631    }
632    /// Insert a **non-standard** attribute by mutable reference.
633    /// # Info
634    /// The attribute name must contains ':', else the  `extra:` prefix is added.
635    pub fn insert_extra_by_ref<S: Into<String>>(&mut self, key: S, value: Value) {
636      let mut key = key.into();
637      if !key.as_str().contains(':') {
638        key = format!("extra:{}", &key);
639      }
640      self.extra.insert(key, value);
641    }
642    /// Insert a **non-standard** string attribute, taking the ownership and returning itself.
643    /// # Info
644    /// The attribute name must contains ':', else the  `extra:` prefix is added.
645    pub fn insert_extra_str<S: Into<String>, T: Into<String>>(mut self, key: S, value: T) -> Self {
646      self.insert_extra_by_ref(key, Value::String(value.into()));
647      self
648    }
649    /// Insert a **non-standard** string attribute by mutable reference.
650    /// # Info
651    /// The attribute name must contains ':', else the  `extra:` prefix is added.
652    pub fn insert_extra_str_by_ref<S: Into<String>, T: Into<String>>(&mut self, key: S, value: T) {
653      self.insert_extra_by_ref(key, Value::String(value.into()))
654    }
655  };
656}
657
658macro_rules! impl_builder_insert_extra_delegated {
659  ($del:ident) => {
660    /// Insert a **non-standard** attribute, taking the ownership and returning itself.
661    /// # Info
662    /// The attribute name must contains ':', else the  `extra:` prefix is added.
663    pub fn insert_extra<S: Into<String>>(mut self, key: S, value: Value) -> Self {
664      self.insert_extra_by_ref(key, value);
665      self
666    }
667    /// Insert a **non-standard** attribute by mutable reference.
668    /// # Info
669    /// The attribute name must contains ':', else the  `extra:` prefix is added.
670    pub fn insert_extra_by_ref<S: Into<String>>(&mut self, key: S, value: Value) {
671      let mut key = key.into();
672      if !key.as_str().contains(':') {
673        key = format!("extra:{}", &key);
674      }
675      self.$del.extra.insert(key, value);
676    }
677    /// Insert a **non-standard** string attribute, taking the ownership and returning itself.
678    /// # Info
679    /// The attribute name must contains ':', else the  `extra:` prefix is added.
680    pub fn insert_extra_str<S: Into<String>, T: Into<String>>(mut self, key: S, value: T) -> Self {
681      self.insert_extra_by_ref(key, Value::String(value.into()));
682      self
683    }
684    /// Insert a **non-standard** string attribute by mutable reference.
685    /// # Info
686    /// The attribute name must contains ':', else the  `extra:` prefix is added.
687    pub fn insert_extra_str_by_ref<S: Into<String>, T: Into<String>>(&mut self, key: S, value: T) {
688      self.insert_extra_by_ref(key, Value::String(value.into()))
689    }
690  };
691}
692
693/*
694/// Read a tag content (without sub-elements)
695macro_rules! read_content_by_ref {
696  ($Self:ident, $self:ident, $reader:ident, $reader_buff:ident) => {{
697    let mut content = String::new();
698    loop {
699      let mut event = $reader
700        .read_event($reader_buff)
701        .map_err(VOTableError::Read)?;
702      match &mut event {
703        Event::Text(e) => content.push_str(
704          e.unescape_and_decode(&$reader)
705            .map_err(VOTableError::Read)?
706            .as_str(),
707        ),
708        Event::CData(e) => content
709          .push_str(str::from_utf8(e.clone().into_inner().as_ref()).map_err(VOTableError::Utf8)?),
710        Event::End(e) if e.local_name() == $Self::TAG_BYTES => {
711          $self.content = Some(content);
712          return Ok(());
713        }
714        Event::Eof => return Err(VOTableError::PrematureEOF(Self::TAG)),
715        Event::Comment(e) => discard_comment(e, &$reader, Self::TAG),
716        _ => discard_event(event, Self::TAG),
717      }
718    }
719  }};
720  ($Self:ident, $self:ident, $reader:ident, $reader_buff:ident, $content:tt) => {{
721    let mut content = String::new();
722    loop {
723      let mut event = $reader
724        .read_event($reader_buff)
725        .map_err(VOTableError::Read)?;
726      match &mut event {
727        Event::Text(e) => content.push_str(
728          e.unescape_and_decode(&$reader)
729            .map_err(VOTableError::Read)?
730            .as_str(),
731        ),
732        Event::CData(e) => content.push_str(
733          std::str::from_utf8(e.clone().into_inner().as_ref()).map_err(VOTableError::Utf8)?,
734        ),
735        Event::End(e) if e.local_name() == $Self::TAG_BYTES => {
736          $self.$content = content;
737          return Ok(());
738        }
739        Event::Eof => return Err(VOTableError::PrematureEOF(Self::TAG)),
740        Event::Comment(e) => discard_comment(e, &$reader, Self::TAG),
741        _ => discard_event(event, Self::TAG),
742      }
743    }
744  }};
745}*/
746
747/// E.g. `write_opt_string_attr(self, elem_writer, ID)` leads to
748/// ```ignore
749/// if let Some(id) = self.id.as_ref() {
750///     elem_writer.with_attribute(("ID", id));
751/// }
752/// ```
753macro_rules! write_opt_string_attr {
754  ($self:ident, $elem_writer:ident, $arg:ident) => {
755    paste! {
756      if let Some([<$arg:lower>]) = $self.[<$arg:lower>].as_ref() {
757        $elem_writer = $elem_writer.with_attribute((stringify!($arg), [<$arg:lower>].as_str()));
758      }
759    }
760  };
761  ($self:ident, $elem_writer:ident, $arg:ident, $arg_str:literal) => {
762    paste! {
763      if let Some([<$arg:lower>]) = $self.[<$arg:lower>].as_ref() {
764        $elem_writer = $elem_writer.with_attribute(($arg_str, [<$arg:lower>].as_str()));
765      }
766    }
767  };
768}
769
770macro_rules! write_opt_tostring_attr {
771  ($self:ident, $elem_writer:ident, $arg:ident) => {
772    paste! {
773      if let Some([<$arg:lower>]) = $self.[<$arg:lower>].as_ref() {
774        $elem_writer = $elem_writer.with_attribute((stringify!($arg), [<$arg:lower>].to_string().as_str()));
775      }
776    }
777  };
778  ($self:ident, $elem_writer:ident, $arg:ident, $arg_str:literal) => {
779    paste! {
780      if let Some([<$arg:lower>]) = $self.[<$arg:lower>].as_ref() {
781        $elem_writer = $elem_writer.with_attribute(($arg_str, [<$arg:lower>].to_string().as_str()));
782      }
783    }
784  };
785}
786
787macro_rules! for_each_extra_attribute {
788  ($self:ident, $f:ident) => {
789    for (k, v) in &$self.extra {
790      match v {
791        Value::Null => $f(k.as_str(), ""),
792        Value::Bool(v) => $f(k.as_str(), v.to_string().as_str()),
793        Value::Number(v) => $f(k.as_str(), v.to_string().as_str()),
794        Value::String(v) => $f(k.as_str(), v.to_string().as_str()),
795        Value::Array(_) => $f(k.as_str(), v.to_string().as_str()),
796        Value::Object(_) => $f(k.as_str(), v.to_string().as_str()),
797      }
798    }
799  };
800}
801
802macro_rules! for_each_extra_attribute_delegated {
803  ($self:ident, $del:ident, $f:ident) => {
804    for (k, v) in &$self.$del.extra {
805      match v {
806        Value::Null => $f(k.as_str(), ""),
807        Value::Bool(v) => $f(k.as_str(), v.to_string().as_str()),
808        Value::Number(v) => $f(k.as_str(), v.to_string().as_str()),
809        Value::String(v) => $f(k.as_str(), v.to_string().as_str()),
810        Value::Array(_) => $f(k.as_str(), v.to_string().as_str()),
811        Value::Object(_) => $f(k.as_str(), v.to_string().as_str()),
812      }
813    }
814  };
815}
816
817/*
818macro_rules! impl_read_write_content_only {
819  () => {
820    fn read_sub_elements_by_ref<R: BufRead>(
821      &mut self,
822      reader: &mut Reader<R>,
823      reader_buff: &mut Vec<u8>,
824      _context: &Self::Context,
825    ) -> Result<(), VOTableError> {
826      read_content_by_ref!(Self, self, reader, reader_buff)
827    }
828
829    fn write_sub_elements_by_ref<W: Write>(
830      &mut self,
831      _writer: &mut Writer<W>,
832      _context: &Self::Context,
833    ) -> Result<(), VOTableError> {
834      unreachable!()
835    }
836  };
837}*/
838
839macro_rules! write_elem {
840  ($self:ident, $elem:ident, $writer:ident, $context:ident) => {
841    if let Some(elem) = &mut $self.$elem {
842      elem.write($writer, $context)?;
843    }
844  };
845}
846
847macro_rules! write_elem_vec {
848  ($self:ident, $elems:ident, $writer:ident, $context:ident) => {
849    for elem in &mut $self.$elems {
850      elem.write($writer, $context)?;
851    }
852  };
853}
854
855macro_rules! write_elem_vec_no_context {
856  ($self:ident, $elems:ident, $writer:ident) => {
857    for elem in &mut $self.$elems {
858      elem.write($writer)?;
859    }
860  };
861}
862
863macro_rules! write_elem_vec_empty_context {
864  ($self:ident, $elems:ident, $writer:ident) => {
865    for elem in &mut $self.$elems {
866      elem.write($writer, &())?;
867    }
868  };
869}
870
871// We use a macro because of mutable borrowing issue with 'reader_buff' if we put this in a function.
872macro_rules! from_event_start_by_ref {
873  ($elem:ident, $reader:ident, $reader_buff:ident, $e:ident) => {{
874    $elem::from_event_start($e)
875      .and_then(|elem| elem.read_content(&mut $reader, &mut $reader_buff, &()))?
876  }};
877  ($elem:ident, $reader:ident, $reader_buff:ident, $e:ident, $context:expr) => {{
878    $elem::from_event_start($e)
879      .and_then(|elem| elem.read_content(&mut $reader, &mut $reader_buff, &$context))?
880  }};
881}
882
883macro_rules! set_from_event_start {
884  ($self:ident, $elem:ident, $reader:ident, $reader_buff:ident, $e:ident) => {
885    paste! {
886      $elem::from_event_start($e)
887        .and_then(|elem| elem.read_content($reader, $reader_buff, &()))
888        .map(|elem| $self.[<set_ $elem:lower _by_ref>](elem))?
889    }
890  };
891  ($self:ident, $elem:ident, $reader:ident, $reader_buff:ident, $e:ident, $context:expr) => {
892    paste! {
893      $elem::from_event_start($e)
894        .and_then(|elem| elem.read_content($reader, $reader_buff, &$context))
895        .map(|elem| $self.[<set_ $elem:lower _by_ref>](elem))?
896    }
897  };
898}
899
900macro_rules! set_from_event_empty {
901  ($self:ident, $elem:ident, $e:ident) => {
902    paste! {
903      $elem::from_event_empty($e)
904        .map(|elem| $self.[<set_ $elem:lower _by_ref>](elem))?
905    }
906  };
907}
908
909macro_rules! set_desc_from_event_start {
910  ($self:ident, $reader:ident, $reader_buff:ident, $e:ident) => {
911    set_from_event_start!($self, Description, $reader, $reader_buff, $e)
912  };
913}
914
915macro_rules! push_from_event_start {
916  ($self:ident, $elem:ident, $reader:ident, $reader_buff:ident, $e:ident) => {
917    paste! {
918      $elem::from_event_start($e)
919      .and_then(|elem| elem.read_content(&mut $reader, &mut $reader_buff, &()))
920      .map(|elem| $self.[<push_ $elem:lower _by_ref>](elem))?
921    }
922  };
923  ($self:ident, $elem:ident, $reader:ident, $reader_buff:ident, $e:ident, $context:expr) => {
924    paste! {
925      $elem::from_event_start($e)
926      .and_then(|elem| elem.read_content(&mut $reader, &mut $reader_buff, &$context))
927      .map(|elem| $self.[<push_ $elem:lower _by_ref>](elem))?
928    }
929  };
930}
931
932macro_rules! push_from_event_empty {
933  ($self:ident, $elem:ident, $e:ident) => {
934    paste! {
935      $elem::from_event_empty($e)
936      .map(|elem| $self.[<push_ $elem:lower _by_ref>](elem))?
937    }
938  };
939}