Skip to main content

zvariant_utils/signature/
fields.rs

1use super::Signature;
2
3/// Signatures of the fields of a [`Signature::Structure`].
4#[derive(Debug, Clone)]
5pub enum Fields {
6    Static {
7        fields: &'static [&'static Signature],
8    },
9    Dynamic {
10        fields: Box<[Signature]>,
11    },
12}
13
14impl Fields {
15    /// A iterator over the fields' signatures.
16    pub fn iter(&self) -> impl Iterator<Item = &Signature> {
17        use std::slice::Iter;
18
19        enum Fields<'a> {
20            Static(Iter<'static, &'static Signature>),
21            Dynamic(Iter<'a, Signature>),
22        }
23
24        impl<'a> Iterator for Fields<'a> {
25            type Item = &'a Signature;
26
27            fn next(&mut self) -> Option<Self::Item> {
28                match self {
29                    Fields::Static(iter) => iter.next().copied(),
30                    Fields::Dynamic(iter) => iter.next(),
31                }
32            }
33        }
34
35        match self {
36            Self::Static { fields } => Fields::Static(fields.iter()),
37            Self::Dynamic { fields } => Fields::Dynamic(fields.iter()),
38        }
39    }
40
41    /// The field signature at index `i`, or `None` if `i >= self.len()`.
42    ///
43    /// Constant-time positional access.
44    pub fn get(&self, i: usize) -> Option<&Signature> {
45        match self {
46            Self::Static { fields } => fields.get(i).copied(),
47            Self::Dynamic { fields } => fields.get(i),
48        }
49    }
50
51    /// The number of fields.
52    pub const fn len(&self) -> usize {
53        match self {
54            Self::Static { fields } => fields.len(),
55            Self::Dynamic { fields } => fields.len(),
56        }
57    }
58
59    /// Whether there are no fields.
60    pub fn is_empty(&self) -> bool {
61        self.len() == 0
62    }
63}
64
65impl From<Box<[Signature]>> for Fields {
66    fn from(fields: Box<[Signature]>) -> Self {
67        Fields::Dynamic { fields }
68    }
69}
70
71impl From<Vec<Signature>> for Fields {
72    fn from(fields: Vec<Signature>) -> Self {
73        Fields::Dynamic {
74            fields: fields.into(),
75        }
76    }
77}
78
79impl<const N: usize> From<[Signature; N]> for Fields {
80    fn from(fields: [Signature; N]) -> Self {
81        Fields::Dynamic {
82            fields: fields.into(),
83        }
84    }
85}
86
87impl From<&'static [&'static Signature]> for Fields {
88    fn from(fields: &'static [&'static Signature]) -> Self {
89        Fields::Static { fields }
90    }
91}