1#[macro_export]
3macro_rules! inner_enum {
4 ($ty:ident, $var:ident) => {
6 inner_enum!($ty, $var, $var);
7 };
8
9 ($ty:ident, $var:ident, $var_ty:ident) => {
11 impl $ty {
12 ::paste::paste! {
13 #[doc = "Gets whether `" $ty "` is the variant `" $var "`."]
14 pub fn [<is_ $var:snake>](&self) -> bool {
15 matches!(self, $ty::$var(_))
16 }
17
18 #[doc = "Gets a reference to `" $ty "` as the variant `" $var "`'s inner type `" $var_ty "`."]
19 #[allow(unreachable_patterns)]
20 pub fn [<as_ $var:snake>](&self) -> $crate::Result<&$var_ty> {
21 use $crate::Error;
22
23 match self {
24 $ty::$var(ty) => Ok(ty),
25 _ => Err(Error::Enum(format!("have variant: {self}, expected: {}", ::std::any::type_name::<$var_ty>()))),
26 }
27 }
28
29 #[doc = "Converts `" $ty "` into the variant `" $var "`'s inner type `" $var_ty "`."]
30 #[allow(unreachable_patterns)]
31 pub fn [<into_ $var:snake>](self) -> $crate::Result<$var_ty> {
32 use $crate::Error;
33
34 match self {
35 $ty::$var(ty) => Ok(ty),
36 _ => Err(Error::Enum(format!("have variant: {self}, expected: {}", ::std::any::type_name::<$var_ty>()))),
37 }
38 }
39 }
40 }
41 };
42}
43
44#[macro_export]
46macro_rules! impl_default {
47 ($ty:ident) => {
48 impl Default for $ty {
49 fn default() -> Self {
50 $ty::new()
51 }
52 }
53 };
54}
55
56#[macro_export]
58macro_rules! impl_xfs_enum {
59 ($ty:ident, $name:expr) => {
60 impl $ty {
61 pub const fn inner(&self) -> u32 {
63 *self as u32
64 }
65
66 pub fn into_inner(self) -> u32 {
68 self as u32
69 }
70 }
71
72 $crate::impl_xfs_i4!($ty, $name);
73 };
74}
75
76#[macro_export]
78macro_rules! create_xfs_i4 {
79 ($ty:ident, $name:expr, $doc:expr) => {
80 ::paste::paste! {
81 #[doc = $doc]
82 #[repr(C)]
83 #[derive(Clone, Copy, Debug, Default, Eq, PartialEq, ::serde::Deserialize, ::serde::Serialize)]
84 pub struct $ty(u32);
85
86 impl $ty {
87 #[doc = "Creates a new `" $ty "`."]
88 pub const fn new() -> Self {
89 Self(0)
90 }
91
92 #[doc = "Creates a new `" $ty "` from the provided parameter."]
93 pub const fn create(val: u32) -> Self {
94 Self(val)
95 }
96
97 #[doc = "Gets the inner representation of `" $ty "`."]
98 pub const fn inner(&self) -> u32 {
99 self.0
100 }
101
102 #[doc = "Sets the inner representation of `" $ty "`."]
103 pub fn set_inner(&mut self, val: u32) {
104 self.0 = val;
105 }
106
107 #[doc = "Converts into the inner representation of `" $ty "`."]
108 pub fn into_inner(self) -> u32 {
109 self.0
110 }
111 }
112
113 $crate::impl_xfs_i4!($ty, $name);
114
115 impl ::std::fmt::Display for $ty {
116 fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
117 write!(f, "{}", self.inner())
118 }
119 }
120 }
121 }
122}
123
124#[macro_export]
126macro_rules! impl_xfs_i4 {
127 ($ty:ident, $name:expr) => {
128 impl $ty {
129 pub const fn xfs_name() -> &'static str {
131 $name
132 }
133 }
134
135 impl From<u32> for $ty {
136 fn from(val: u32) -> Self {
137 Self::create(val)
138 }
139 }
140
141 impl From<&u32> for $ty {
142 fn from(val: &u32) -> Self {
143 (*val).into()
144 }
145 }
146
147 impl From<$ty> for u32 {
148 fn from(val: $ty) -> Self {
149 val.inner()
150 }
151 }
152
153 impl From<&$ty> for u32 {
154 fn from(val: &$ty) -> Self {
155 (*val).into()
156 }
157 }
158
159 impl From<i32> for $ty {
160 fn from(val: i32) -> Self {
161 (val as u32).into()
162 }
163 }
164
165 impl From<&i32> for $ty {
166 fn from(val: &i32) -> Self {
167 (*val).into()
168 }
169 }
170
171 impl From<$ty> for i32 {
172 fn from(val: $ty) -> Self {
173 val.inner() as i32
174 }
175 }
176
177 impl From<&$ty> for i32 {
178 fn from(val: &$ty) -> Self {
179 (*val).into()
180 }
181 }
182
183 impl From<&$ty> for $crate::xfs::value::XfsValue {
184 fn from(val: &$ty) -> Self {
185 Self::new().with_i4(val.into())
186 }
187 }
188
189 impl From<$ty> for $crate::xfs::value::XfsValue {
190 fn from(val: $ty) -> Self {
191 (&val).into()
192 }
193 }
194
195 impl TryFrom<&$crate::xfs::value::XfsValue> for $ty {
196 type Error = $crate::Error;
197
198 fn try_from(val: &$crate::xfs::value::XfsValue) -> $crate::Result<Self> {
199 let name = $ty::xfs_name();
200 Ok(val
201 .i4()
202 .ok_or($crate::Error::Xfs(format!(
203 "Expected {name} XfsValue, have: {val}"
204 )))?
205 .into())
206 }
207 }
208
209 impl TryFrom<$crate::xfs::value::XfsValue> for $ty {
210 type Error = $crate::Error;
211
212 fn try_from(val: $crate::xfs::value::XfsValue) -> $crate::Result<Self> {
213 (&val).try_into()
214 }
215 }
216
217 impl From<&$ty> for $crate::xfs::xfs_struct::XfsMember {
218 fn from(val: &$ty) -> Self {
219 $crate::xfs::xfs_struct::XfsMember::create($ty::xfs_name(), val.into())
220 }
221 }
222
223 impl From<$ty> for $crate::xfs::xfs_struct::XfsMember {
224 fn from(val: $ty) -> Self {
225 (&val).into()
226 }
227 }
228
229 impl TryFrom<&$crate::xfs::xfs_struct::XfsMember> for $ty {
230 type Error = $crate::Error;
231
232 fn try_from(val: &$crate::xfs::xfs_struct::XfsMember) -> $crate::Result<Self> {
233 let name = $ty::xfs_name();
234 match (val.name(), val.value().i4()) {
235 (n, Some(v)) if n == name => Ok(v.into()),
236 _ => Err($crate::Error::Xfs(format!(
237 "Expected {name} XfsMember, have: {val}"
238 ))),
239 }
240 }
241 }
242
243 impl TryFrom<$crate::xfs::xfs_struct::XfsMember> for $ty {
244 type Error = $crate::Error;
245
246 fn try_from(val: $crate::xfs::xfs_struct::XfsMember) -> $crate::Result<Self> {
247 (&val).try_into()
248 }
249 }
250 };
251}
252
253#[macro_export]
255macro_rules! impl_xfs_int {
256 ($ty:ident, $name:expr) => {
257 impl $ty {
258 pub const fn xfs_name() -> &'static str {
260 $name
261 }
262 }
263
264 impl From<u64> for $ty {
265 fn from(val: u64) -> Self {
266 Self::create(val)
267 }
268 }
269
270 impl From<&u64> for $ty {
271 fn from(val: &u64) -> Self {
272 (*val).into()
273 }
274 }
275
276 impl From<&$ty> for u64 {
277 fn from(val: &$ty) -> Self {
278 val.inner()
279 }
280 }
281
282 impl From<$ty> for u64 {
283 fn from(val: $ty) -> Self {
284 val.into_inner()
285 }
286 }
287
288 impl From<i64> for $ty {
289 fn from(val: i64) -> Self {
290 (val as u64).into()
291 }
292 }
293
294 impl From<&i64> for $ty {
295 fn from(val: &i64) -> Self {
296 (*val).into()
297 }
298 }
299
300 impl From<$ty> for i64 {
301 fn from(val: $ty) -> Self {
302 val.into_inner() as i64
303 }
304 }
305
306 impl From<&$ty> for i64 {
307 fn from(val: &$ty) -> Self {
308 val.inner() as i64
309 }
310 }
311
312 impl From<&$ty> for $crate::xfs::value::XfsValue {
313 fn from(val: &$ty) -> Self {
314 Self::new().with_int(val.into())
315 }
316 }
317
318 impl From<$ty> for $crate::xfs::value::XfsValue {
319 fn from(val: $ty) -> Self {
320 Self::new().with_int(val.into())
321 }
322 }
323
324 impl TryFrom<&$crate::xfs::value::XfsValue> for $ty {
325 type Error = $crate::Error;
326
327 fn try_from(val: &$crate::xfs::value::XfsValue) -> $crate::Result<Self> {
328 let name = $ty::xfs_name();
329 Ok(val
330 .int()
331 .ok_or($crate::Error::Xfs(format!(
332 "Expected {name} XfsValue, have: {val}"
333 )))?
334 .into())
335 }
336 }
337
338 impl TryFrom<$crate::xfs::value::XfsValue> for $ty {
339 type Error = $crate::Error;
340
341 fn try_from(val: $crate::xfs::value::XfsValue) -> $crate::Result<Self> {
342 (&val).try_into()
343 }
344 }
345
346 impl From<&$ty> for $crate::xfs::xfs_struct::XfsMember {
347 fn from(val: &$ty) -> Self {
348 $crate::xfs::xfs_struct::XfsMember::create($ty::xfs_name(), val.into())
349 }
350 }
351
352 impl From<$ty> for $crate::xfs::xfs_struct::XfsMember {
353 fn from(val: $ty) -> Self {
354 (&val).into()
355 }
356 }
357
358 impl TryFrom<&$crate::xfs::xfs_struct::XfsMember> for $ty {
359 type Error = $crate::Error;
360
361 fn try_from(val: &$crate::xfs::xfs_struct::XfsMember) -> $crate::Result<Self> {
362 let name = $ty::xfs_name();
363 match (val.name(), val.value().int()) {
364 (n, Some(v)) if n == name => Ok(v.into()),
365 _ => Err($crate::Error::Xfs(format!(
366 "Expected {name} XfsMember, have: {val}"
367 ))),
368 }
369 }
370 }
371
372 impl TryFrom<$crate::xfs::xfs_struct::XfsMember> for $ty {
373 type Error = $crate::Error;
374
375 fn try_from(val: $crate::xfs::xfs_struct::XfsMember) -> $crate::Result<Self> {
376 (&val).try_into()
377 }
378 }
379 };
380}
381
382#[macro_export]
384macro_rules! create_xfs_bool {
385 ($ty:ident, $name:expr, $doc:expr) => {
386 ::paste::paste! {
387 #[doc = $doc]
388 #[repr(C)]
389 #[derive(Clone, Copy, Debug, Default, PartialEq, ::serde::Deserialize, ::serde::Serialize)]
390 pub struct $ty(bool);
391
392 impl $ty {
393 #[doc = "Creates a new `" $ty "`."]
394 pub const fn new() -> Self {
395 Self(false)
396 }
397
398 #[doc = "Creates a new `" $ty "` from the provided parameter."]
399 pub const fn create(val: bool) -> Self {
400 Self(val)
401 }
402
403 #[doc = "Gets the inner representation of `" $ty "`."]
404 pub const fn inner(&self) -> bool {
405 self.0
406 }
407
408 #[doc = "Sets the inner representation of `" $ty "`."]
409 pub fn set_inner(&mut self, val: bool) {
410 self.0 = val;
411 }
412
413 #[doc = "Converts into the inner representation of `" $ty "`."]
414 pub fn into_inner(self) -> bool {
415 self.0
416 }
417 }
418
419 $crate::impl_xfs_bool!($ty, $name);
420
421 impl ::std::fmt::Display for $ty {
422 fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
423 write!(f, "{}", self.inner())
424 }
425 }
426 }
427 }
428}
429
430#[macro_export]
432macro_rules! impl_xfs_bool {
433 ($ty:ident, $name:expr) => {
434 impl $ty {
435 pub const fn xfs_name() -> &'static str {
437 $name
438 }
439 }
440
441 impl From<bool> for $ty {
442 fn from(val: bool) -> Self {
443 Self::create(val)
444 }
445 }
446
447 impl From<&bool> for $ty {
448 fn from(val: &bool) -> Self {
449 (*val).into()
450 }
451 }
452
453 impl From<u8> for $ty {
454 fn from(val: u8) -> Self {
455 Self::create(val != 0)
456 }
457 }
458
459 impl From<&u8> for $ty {
460 fn from(val: &u8) -> Self {
461 (*val).into()
462 }
463 }
464
465 impl From<&$ty> for bool {
466 fn from(val: &$ty) -> Self {
467 val.inner()
468 }
469 }
470
471 impl From<$ty> for bool {
472 fn from(val: $ty) -> Self {
473 (&val).into()
474 }
475 }
476
477 impl From<&$ty> for u8 {
478 fn from(val: &$ty) -> Self {
479 val.inner() as u8
480 }
481 }
482
483 impl From<$ty> for u8 {
484 fn from(val: $ty) -> Self {
485 (&val).into()
486 }
487 }
488
489 impl From<&$ty> for $crate::xfs::value::XfsValue {
490 fn from(val: &$ty) -> Self {
491 Self::new().with_boolean(val.into())
492 }
493 }
494
495 impl From<$ty> for $crate::xfs::value::XfsValue {
496 fn from(val: $ty) -> Self {
497 (&val).into()
498 }
499 }
500
501 impl TryFrom<&$crate::xfs::value::XfsValue> for $ty {
502 type Error = $crate::Error;
503
504 fn try_from(val: &$crate::xfs::value::XfsValue) -> $crate::Result<Self> {
505 let name = $ty::xfs_name();
506 Ok(val
507 .boolean()
508 .ok_or($crate::Error::Xfs(format!(
509 "Expected {name} XfsValue, have: {val}"
510 )))?
511 .into())
512 }
513 }
514
515 impl TryFrom<$crate::xfs::value::XfsValue> for $ty {
516 type Error = $crate::Error;
517
518 fn try_from(val: $crate::xfs::value::XfsValue) -> $crate::Result<Self> {
519 (&val).try_into()
520 }
521 }
522
523 impl From<&$ty> for $crate::xfs::xfs_struct::XfsMember {
524 fn from(val: &$ty) -> Self {
525 $crate::xfs::xfs_struct::XfsMember::create($ty::xfs_name(), val.into())
526 }
527 }
528
529 impl From<$ty> for $crate::xfs::xfs_struct::XfsMember {
530 fn from(val: $ty) -> Self {
531 (&val).into()
532 }
533 }
534
535 impl TryFrom<&$crate::xfs::xfs_struct::XfsMember> for $ty {
536 type Error = $crate::Error;
537
538 fn try_from(val: &$crate::xfs::xfs_struct::XfsMember) -> $crate::Result<Self> {
539 let name = $ty::xfs_name();
540 match (val.name(), val.value().boolean()) {
541 (n, Some(v)) if n == name => Ok(v.into()),
542 _ => Err($crate::Error::Xfs(format!(
543 "Expected {name} XfsMember, have: {val}"
544 ))),
545 }
546 }
547 }
548
549 impl TryFrom<$crate::xfs::xfs_struct::XfsMember> for $ty {
550 type Error = $crate::Error;
551
552 fn try_from(val: $crate::xfs::xfs_struct::XfsMember) -> $crate::Result<Self> {
553 (&val).try_into()
554 }
555 }
556 };
557}
558
559#[macro_export]
570macro_rules! create_xfs_struct {
571 ($ty:ident, $name:expr, [$($field_name:ident: $field_ty:ident),*], $doc:expr) => {
572 ::paste::paste! {
573 #[doc = $doc]
574 #[repr(C)]
575 #[derive(Clone, Debug, PartialEq)]
576 pub struct $ty {
577 $($field_name: $field_ty),*
578 }
579
580 impl $ty {
581 #[doc = "Creates a new [" $ty "]."]
582 pub const fn new() -> Self {
583 Self {
584 $($field_name: $field_ty::new()),*
585 }
586 }
587
588 $(
589 #[doc = "Gets the [" $field_ty "] for [" $ty "]."]
590 pub const fn $field_name(&self) -> &$field_ty {
591 &self.$field_name
592 }
593
594 #[doc = "Sets the [" $field_ty "] for [" $ty "]."]
595 pub fn [<set_ $field_name>](&mut self, val: $field_ty) {
596 self.$field_name = val;
597 }
598
599 #[doc = "Builder function that sets the [" $field_ty "] for [" $ty "]."]
600 pub fn [<with_ $field_name>](mut self, val: $field_ty) -> Self {
601 self.[<set_ $field_name>](val);
602 self
603 }
604 )*
605 }
606
607 impl ::std::fmt::Display for $ty {
608 fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
609 write!(f, "{{")?;
610 write!(f, r#""name": "{}""#, $name)?;
611 $(
612 write!(f, r#","{}": {}"#, stringify!($field_name), self.$field_name)?;
613 )*
614 write!(f, "}}")
615 }
616 }
617
618 impl Default for $ty {
619 fn default() -> Self {
620 $ty::new()
621 }
622 }
623
624 $crate::impl_xfs_struct!($ty, $name, [$($field_name: $field_ty),*]);
625 }
626 }
627}
628
629#[macro_export]
640macro_rules! impl_xfs_struct {
641 ($ty:ident, $name:expr, [$($field_name:ident: $field_ty:ident),*]) => {
642 impl $ty {
643 pub const fn xfs_name() -> &'static str {
645 $name
646 }
647 }
648
649 impl From<&$ty> for $crate::xfs::xfs_struct::XfsStruct {
650 fn from(val: &$ty) -> Self {
651 Self::create([
652 $(val.$field_name.clone().into(),)*
653 ])
654 }
655 }
656
657 impl From<$ty> for $crate::xfs::xfs_struct::XfsStruct {
658 fn from(val: $ty) -> Self {
659 (&val).into()
660 }
661 }
662
663 impl TryFrom<&$crate::xfs::xfs_struct::XfsStruct> for $ty {
664 type Error = $crate::Error;
665
666 #[allow(clippy::needless_update)]
667 fn try_from(val: &$crate::xfs::xfs_struct::XfsStruct) -> $crate::Result<Self> {
668 Ok(Self {
669 $(
670 $field_name: match val.find_member($field_ty::xfs_name()) {
671 Ok(m) => m.try_into()?,
672 Err(_err) => {
673 ::log::warn!("Missing member {} from {}", stringify!($field_name), stringify!($ty));
674 $field_ty::new()
675 }
676 },
677 )*
678 ..Default::default()
679 })
680 }
681 }
682
683 impl TryFrom<$crate::xfs::xfs_struct::XfsStruct> for $ty {
684 type Error = $crate::Error;
685
686 fn try_from(val: $crate::xfs::xfs_struct::XfsStruct) -> $crate::Result<Self> {
687 (&val).try_into()
688 }
689 }
690
691 impl From<&$ty> for $crate::xfs::value::XfsValue {
692 fn from(val: &$ty) -> Self {
693 Self::new().with_xfs_struct(val.into())
694 }
695 }
696
697 impl From<$ty> for $crate::xfs::value::XfsValue {
698 fn from(val: $ty) -> Self {
699 (&val).into()
700 }
701 }
702
703 impl TryFrom<&$crate::xfs::value::XfsValue> for $ty {
704 type Error = $crate::Error;
705
706 fn try_from(val: &$crate::xfs::value::XfsValue) -> $crate::Result<Self> {
707 let name = $ty::xfs_name();
708 val
709 .xfs_struct()
710 .ok_or($crate::Error::Xfs(format!(
711 "Expected {name} XfsValue, have: {val}"
712 )))?
713 .try_into()
714 }
715 }
716
717 impl TryFrom<$crate::xfs::value::XfsValue> for $ty {
718 type Error = $crate::Error;
719
720 fn try_from(val: $crate::xfs::value::XfsValue) -> $crate::Result<Self> {
721 (&val).try_into()
722 }
723 }
724
725 impl From<&$ty> for $crate::xfs::xfs_struct::XfsMember {
726 fn from(val: &$ty) -> Self {
727 $crate::xfs::xfs_struct::XfsMember::create($ty::xfs_name(), val.into())
728 }
729 }
730
731 impl From<$ty> for $crate::xfs::xfs_struct::XfsMember {
732 fn from(val: $ty) -> Self {
733 (&val).into()
734 }
735 }
736
737 impl TryFrom<&$crate::xfs::xfs_struct::XfsMember> for $ty {
738 type Error = $crate::Error;
739
740 fn try_from(val: &$crate::xfs::xfs_struct::XfsMember) -> $crate::Result<Self> {
741 let name = $ty::xfs_name();
742 match (val.name(), val.value().xfs_struct()) {
743 (n, Some(v)) if n == name => v.try_into(),
744 _ => Err($crate::Error::Xfs(format!(
745 "Expected {name} XfsMember, have: {val}"
746 ))),
747 }
748 }
749 }
750
751 impl TryFrom<$crate::xfs::xfs_struct::XfsMember> for $ty {
752 type Error = $crate::Error;
753
754 fn try_from(val: $crate::xfs::xfs_struct::XfsMember) -> $crate::Result<Self> {
755 (&val).try_into()
756 }
757 }
758 };
759}
760
761#[macro_export]
762macro_rules! create_xfs_array {
763 ($ty:ident, $name:expr, $item:ident, $len:expr, $default:expr, $doc:expr) => {
764 ::paste::paste! {
765 #[doc = $doc]
766 #[repr(C)]
767 #[derive(Clone, Debug, PartialEq)]
768 pub struct $ty{
769 size: usize,
770 items: [$item; $len],
771 }
772
773 impl $ty {
774 #[doc = "Creates a new [" $ty "]."]
775 pub const fn new() -> Self {
776 Self {
777 size: 0,
778 items: [$default; $len],
779 }
780 }
781
782 #[doc = "Gets the maximum number of [" $ty "] items."]
783 pub const fn max_size() -> usize {
784 $len
785 }
786
787 #[doc = "Gets the size of the [" $ty "]."]
788 pub const fn size(&self) -> usize {
789 self.size
790 }
791
792 #[doc = "Sets the size of the [" $ty "]."]
793 #[doc = ""]
794 #[doc = "No-op if `val` is larger than [" $ty "]."]
795 pub fn set_size(&mut self, val: u32) {
796 let size = val as usize;
797 if size <= $len {
798 self.size = size;
799 }
800 }
801
802 #[doc = "Builder function that sets the size of the [" $ty "]."]
803 #[doc = ""]
804 #[doc = "No-op if `val` is larger than [" $ty "]."]
805 pub fn with_size(mut self, val: u32) -> Self {
806 self.set_size(val);
807 self
808 }
809
810 #[doc = "Gets a reference to the list of set [" $ty "] items."]
811 pub fn items(&self) -> &[$item] {
812 let len = ::std::cmp::min(self.size, $len);
813 self.items[..len].as_ref()
814 }
815
816 #[doc = "Sets the list of [" $ty "] items."]
817 pub fn set_items(&mut self, val: &[$item]) {
818 let len = ::std::cmp::min(val.len(), $len);
819 self.items[..len]
820 .iter_mut()
821 .zip(val[..len].iter())
822 .for_each(|(dst, src)| *dst = src.clone());
823 self.items[len..]
824 .iter_mut()
825 .for_each(|item| *item = $item::new());
826 self.size = len;
827 }
828
829 #[doc = "Builder function that sets the list of [" $ty "] items."]
830 pub fn with_items(mut self, val: &[$item]) -> Self {
831 self.set_items(val);
832 self
833 }
834
835 #[doc = "Pushes a [" $ty "] onto the end of the list."]
836 #[doc = ""]
837 #[doc = "No-op if the list is at capacity."]
838 pub fn push_item(&mut self, val: $item) {
839 if self.size < $len {
840 self.items[self.size] = val;
841 self.size += 1;
842 }
843 }
844 }
845
846 impl Default for $ty {
847 fn default() -> Self {
848 Self::new()
849 }
850 }
851
852 impl ::std::fmt::Display for $ty {
853 fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
854 write!(f, r#"{{"items":["#)?;
855 for (i, item) in self.items().iter().enumerate() {
856 if i != 0 {
857 write!(f, ",")?;
858 }
859 write!(f, "{item}")?;
860 }
861 write!(f, "]}}")
862 }
863 }
864
865 $crate::impl_xfs_array!($ty, $name);
866 }
867 };
868}
869
870#[macro_export]
879macro_rules! impl_xfs_array {
880 ($ty:ident, $name:expr) => {
881 impl $ty {
882 pub const fn xfs_name() -> &'static str {
884 $name
885 }
886 }
887
888 impl From<&$ty> for $crate::xfs::array::XfsArray {
889 fn from(val: &$ty) -> Self {
890 Self::create(val.items().iter().map($crate::xfs::value::XfsValue::from))
891 }
892 }
893
894 impl From<$ty> for $crate::xfs::array::XfsArray {
895 fn from(val: $ty) -> Self {
896 (&val).into()
897 }
898 }
899
900 impl TryFrom<&$crate::xfs::array::XfsArray> for $ty {
901 type Error = $crate::Error;
902
903 fn try_from(val: &$crate::xfs::array::XfsArray) -> $crate::Result<Self> {
904 let data = val.data();
905 let mut res = $ty::new();
906
907 let len = ::std::cmp::min($ty::max_size(), data.len());
911 for (i, (dst, src)) in res.items[..len]
912 .iter_mut()
913 .zip(data[..len].iter().map(|m| m.inner()))
914 .enumerate()
915 {
916 match src.try_into() {
917 Ok(d) => *dst = d,
918 Err(err) => log::warn!("Failed to convert item[{i}]: {err}"),
919 }
920 }
921
922 res.set_size(len as u32);
923
924 Ok(res)
925 }
926 }
927
928 impl TryFrom<$crate::xfs::array::XfsArray> for $ty {
929 type Error = $crate::Error;
930
931 fn try_from(val: $crate::xfs::array::XfsArray) -> $crate::Result<Self> {
932 (&val).try_into()
933 }
934 }
935
936 impl From<&$ty> for $crate::xfs::value::XfsValue {
937 fn from(val: &$ty) -> Self {
938 Self::new().with_array(val.into())
939 }
940 }
941
942 impl From<$ty> for $crate::xfs::value::XfsValue {
943 fn from(val: $ty) -> Self {
944 (&val).into()
945 }
946 }
947
948 impl TryFrom<&$crate::xfs::value::XfsValue> for $ty {
949 type Error = $crate::Error;
950
951 fn try_from(val: &$crate::xfs::value::XfsValue) -> $crate::Result<Self> {
952 let name = $ty::xfs_name();
953 val.array()
954 .ok_or($crate::Error::Xfs(format!(
955 "Expected {name} XfsValue, have: {val}"
956 )))?
957 .try_into()
958 }
959 }
960
961 impl TryFrom<$crate::xfs::value::XfsValue> for $ty {
962 type Error = $crate::Error;
963
964 fn try_from(val: $crate::xfs::value::XfsValue) -> $crate::Result<Self> {
965 (&val).try_into()
966 }
967 }
968
969 impl From<&$ty> for $crate::xfs::xfs_struct::XfsMember {
970 fn from(val: &$ty) -> Self {
971 $crate::xfs::xfs_struct::XfsMember::create($ty::xfs_name(), val.into())
972 }
973 }
974
975 impl From<$ty> for $crate::xfs::xfs_struct::XfsMember {
976 fn from(val: $ty) -> Self {
977 (&val).into()
978 }
979 }
980
981 impl TryFrom<&$crate::xfs::xfs_struct::XfsMember> for $ty {
982 type Error = $crate::Error;
983
984 fn try_from(val: &$crate::xfs::xfs_struct::XfsMember) -> $crate::Result<Self> {
985 let name = $ty::xfs_name();
986 match (val.name(), val.value().array()) {
987 (n, Some(v)) if n == name => v.try_into(),
988 _ => Err($crate::Error::Xfs(format!(
989 "Expected {name} XfsMember, have: {val}"
990 ))),
991 }
992 }
993 }
994
995 impl TryFrom<$crate::xfs::xfs_struct::XfsMember> for $ty {
996 type Error = $crate::Error;
997
998 fn try_from(val: $crate::xfs::xfs_struct::XfsMember) -> $crate::Result<Self> {
999 (&val).try_into()
1000 }
1001 }
1002 };
1003}
1004
1005#[macro_export]
1006macro_rules! create_xfs_string {
1007 ($ty:ident, $name:expr, $doc:expr) => {
1008 ::paste::paste! {
1009 #[doc = $doc]
1010 #[derive(Clone, Debug, Eq, PartialEq)]
1011 pub struct $ty(String);
1012
1013 impl $ty {
1014 #[doc = "Creates a new [" $ty "]."]
1015 pub const fn new() -> Self {
1016 Self(String::new())
1017 }
1018
1019 #[doc = "Gets a reference to the [" $ty "] inner representation."]
1020 pub fn inner(&self) -> &str {
1021 self.0.as_str()
1022 }
1023
1024 #[doc = "Sets the [" $ty "] inner representation value."]
1025 pub fn set_inner(&mut self, val: &str) {
1026 self.0 = val.into();
1027 }
1028
1029 #[doc = "Builder function that sets the [" $ty "] inner representation value."]
1030 pub fn with_inner(mut self, val: &str) -> Self {
1031 self.set_inner(val);
1032 self
1033 }
1034
1035 #[doc = "Converts the [" $ty "] into the inner representation."]
1036 pub fn into_inner(self) -> String {
1037 self.0
1038 }
1039 }
1040 }
1041
1042 impl Default for $ty {
1043 fn default() -> Self {
1044 Self::new()
1045 }
1046 }
1047
1048 impl ::std::fmt::Display for $ty {
1049 fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
1050 write!(f, r#""{}""#, self.0)
1051 }
1052 }
1053
1054 $crate::impl_xfs_string!($ty, $name);
1055 };
1056}
1057
1058#[macro_export]
1060macro_rules! impl_xfs_string {
1061 ($ty:ident, $name:expr) => {
1062 impl $ty {
1063 pub const fn xfs_name() -> &'static str {
1065 $name
1066 }
1067 }
1068
1069 impl From<&str> for $ty {
1070 fn from(val: &str) -> Self {
1071 Self(val.into())
1072 }
1073 }
1074
1075 impl From<String> for $ty {
1076 fn from(val: String) -> Self {
1077 Self(val)
1078 }
1079 }
1080
1081 impl From<&$ty> for String {
1082 fn from(val: &$ty) -> Self {
1083 val.inner().into()
1084 }
1085 }
1086
1087 impl From<$ty> for String {
1088 fn from(val: $ty) -> Self {
1089 val.into_inner()
1090 }
1091 }
1092
1093 impl From<&$ty> for $crate::xfs::value::XfsValue {
1094 fn from(val: &$ty) -> Self {
1095 Self::new().with_string(val.inner())
1096 }
1097 }
1098
1099 impl From<$ty> for $crate::xfs::value::XfsValue {
1100 fn from(val: $ty) -> Self {
1101 Self::new().with_string(val.into_inner())
1102 }
1103 }
1104
1105 impl TryFrom<&$crate::xfs::value::XfsValue> for $ty {
1106 type Error = $crate::Error;
1107
1108 fn try_from(val: &$crate::xfs::value::XfsValue) -> $crate::Result<Self> {
1109 Ok(val.string().unwrap_or("").into())
1110 }
1111 }
1112
1113 impl TryFrom<$crate::xfs::value::XfsValue> for $ty {
1114 type Error = $crate::Error;
1115
1116 fn try_from(val: $crate::xfs::value::XfsValue) -> $crate::Result<Self> {
1117 (&val).try_into()
1118 }
1119 }
1120
1121 impl From<&$ty> for $crate::xfs::xfs_struct::XfsMember {
1122 fn from(val: &$ty) -> Self {
1123 $crate::xfs::xfs_struct::XfsMember::create($ty::xfs_name(), val.into())
1124 }
1125 }
1126
1127 impl From<$ty> for $crate::xfs::xfs_struct::XfsMember {
1128 fn from(val: $ty) -> Self {
1129 (&val).into()
1130 }
1131 }
1132
1133 impl TryFrom<&$crate::xfs::xfs_struct::XfsMember> for $ty {
1134 type Error = $crate::Error;
1135
1136 fn try_from(val: &$crate::xfs::xfs_struct::XfsMember) -> $crate::Result<Self> {
1137 let name = $ty::xfs_name();
1138 match (val.name(), val.value().string()) {
1139 (n, Some(v)) if n == name => Ok(v.into()),
1140 (n, None) if n == name => Ok("".into()),
1141 _ => Err($crate::Error::Xfs(format!(
1142 "Expected {name} XfsMember, have: {val}"
1143 ))),
1144 }
1145 }
1146 }
1147
1148 impl TryFrom<$crate::xfs::xfs_struct::XfsMember> for $ty {
1149 type Error = $crate::Error;
1150
1151 fn try_from(val: $crate::xfs::xfs_struct::XfsMember) -> $crate::Result<Self> {
1152 (&val).try_into()
1153 }
1154 }
1155 };
1156}
1157
1158#[macro_export]
1159macro_rules! create_xfs_date_time {
1160 ($ty:ident, $name:expr, $doc:expr) => {
1161 ::paste::paste! {
1162 #[doc = $doc]
1163 #[derive(Clone, Debug, Eq, PartialEq)]
1164 pub struct $ty(String);
1165
1166 impl $ty {
1167 #[doc = "Creates a new [" $ty "]."]
1168 pub const fn new() -> Self {
1169 Self(String::new())
1170 }
1171
1172 #[doc = "Gets a reference to the [" $ty "] inner representation."]
1173 pub fn inner(&self) -> &str {
1174 self.0.as_str()
1175 }
1176
1177 #[doc = "Sets the [" $ty "] inner representation value."]
1178 pub fn set_inner(&mut self, val: &str) {
1179 self.0 = val.into();
1180 }
1181
1182 #[doc = "Builder function that sets the [" $ty "] inner representation value."]
1183 pub fn with_inner(mut self, val: &str) -> Self {
1184 self.set_inner(val);
1185 self
1186 }
1187
1188 #[doc = "Converts the [" $ty "] into the inner representation."]
1189 pub fn into_inner(self) -> String {
1190 self.0
1191 }
1192 }
1193 }
1194
1195 impl Default for $ty {
1196 fn default() -> Self {
1197 Self::new()
1198 }
1199 }
1200
1201 impl TryFrom<&$ty> for ::time::OffsetDateTime {
1202 type Error = $crate::Error;
1203
1204 fn try_from(val: &$ty) -> $crate::Result<Self> {
1205 let date_str = val.inner();
1206 if date_str.len() < 17 {
1207 Err($crate::Error::DateTime(format!(
1208 "invalid ISO-8601 DateTime, too short: {date_str}"
1209 )))
1210 } else {
1211 let mut date_string = date_str.to_string();
1212
1213 date_string.insert(6, '-');
1214 date_string.insert(4, '-');
1215
1216 date_string += "+00:00";
1217
1218 ::log::debug!("Formatted DateTime: {date_string}");
1219
1220 Ok(Self::parse(
1221 date_string.as_str(),
1222 &::time::format_description::well_known::Iso8601::DATE_TIME,
1223 )?)
1224 }
1225 }
1226 }
1227
1228 impl ::std::fmt::Display for $ty {
1229 fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
1230 write!(f, r#""{}""#, self.0)
1231 }
1232 }
1233
1234 $crate::impl_xfs_date_time!($ty, $name);
1235 };
1236}
1237
1238#[macro_export]
1240macro_rules! impl_xfs_date_time {
1241 ($ty:ident, $name:expr) => {
1242 impl $ty {
1243 pub const fn xfs_name() -> &'static str {
1245 $name
1246 }
1247 }
1248
1249 impl From<&str> for $ty {
1250 fn from(val: &str) -> Self {
1251 Self(val.into())
1252 }
1253 }
1254
1255 impl From<String> for $ty {
1256 fn from(val: String) -> Self {
1257 Self(val)
1258 }
1259 }
1260
1261 impl From<&$ty> for String {
1262 fn from(val: &$ty) -> Self {
1263 val.inner().into()
1264 }
1265 }
1266
1267 impl From<$ty> for String {
1268 fn from(val: $ty) -> Self {
1269 val.into_inner()
1270 }
1271 }
1272
1273 impl From<&$ty> for $crate::xfs::value::XfsValue {
1274 fn from(val: &$ty) -> Self {
1275 Self::new().with_date_time(val.inner())
1276 }
1277 }
1278
1279 impl From<$ty> for $crate::xfs::value::XfsValue {
1280 fn from(val: $ty) -> Self {
1281 Self::new().with_date_time(val.into_inner())
1282 }
1283 }
1284
1285 impl TryFrom<&$crate::xfs::value::XfsValue> for $ty {
1286 type Error = $crate::Error;
1287
1288 fn try_from(val: &$crate::xfs::value::XfsValue) -> $crate::Result<Self> {
1289 Ok(val.date_time().unwrap_or("").into())
1290 }
1291 }
1292
1293 impl TryFrom<$crate::xfs::value::XfsValue> for $ty {
1294 type Error = $crate::Error;
1295
1296 fn try_from(val: $crate::xfs::value::XfsValue) -> $crate::Result<Self> {
1297 (&val).try_into()
1298 }
1299 }
1300
1301 impl From<&$ty> for $crate::xfs::xfs_struct::XfsMember {
1302 fn from(val: &$ty) -> Self {
1303 $crate::xfs::xfs_struct::XfsMember::create($ty::xfs_name(), val.into())
1304 }
1305 }
1306
1307 impl From<$ty> for $crate::xfs::xfs_struct::XfsMember {
1308 fn from(val: $ty) -> Self {
1309 (&val).into()
1310 }
1311 }
1312
1313 impl TryFrom<&$crate::xfs::xfs_struct::XfsMember> for $ty {
1314 type Error = $crate::Error;
1315
1316 fn try_from(val: &$crate::xfs::xfs_struct::XfsMember) -> $crate::Result<Self> {
1317 let name = $ty::xfs_name();
1318 match (val.name(), val.value().date_time()) {
1319 (n, Some(v)) if n == name => Ok(v.into()),
1320 (n, None) if n == name => Ok("".into()),
1321 _ => Err($crate::Error::Xfs(format!(
1322 "Expected {name} XfsMember, have: {val}"
1323 ))),
1324 }
1325 }
1326 }
1327
1328 impl TryFrom<$crate::xfs::xfs_struct::XfsMember> for $ty {
1329 type Error = $crate::Error;
1330
1331 fn try_from(val: $crate::xfs::xfs_struct::XfsMember) -> $crate::Result<Self> {
1332 (&val).try_into()
1333 }
1334 }
1335 };
1336}