rasn/types/
variants.rs

1use alloc::{borrow::Cow, vec, vec::Vec};
2
3use crate::types::{Tag, TagTree};
4
5#[derive(Debug, Clone)]
6pub struct Variants {
7    fields: Vec<Tag>,
8}
9
10impl Variants {
11    pub fn new(fields: Cow<'static, [TagTree]>) -> Self {
12        Self::flatten_tree((*fields).iter())
13    }
14
15    pub const fn empty() -> Self {
16        Self { fields: Vec::new() }
17    }
18
19    pub fn from_static(fields: &'static [TagTree]) -> Self {
20        Self::new(Cow::Borrowed(fields))
21    }
22
23    pub fn from_slice(fields: &[TagTree]) -> Self {
24        Self::flatten_tree(fields.iter())
25    }
26
27    fn flatten_tree<'a, I>(field_iter: I) -> Self
28    where
29        I: Iterator<Item = &'a TagTree>,
30    {
31        let fields = field_iter
32            .flat_map(|tree| {
33                fn flatten_tree(tree: &TagTree) -> Vec<Tag> {
34                    match tree {
35                        TagTree::Leaf(tag) => vec![*tag],
36                        TagTree::Choice(tree) => tree.iter().flat_map(flatten_tree).collect(),
37                    }
38                }
39
40                flatten_tree(tree)
41            })
42            .collect();
43
44        Self { fields }
45    }
46}
47
48impl From<Cow<'static, [TagTree]>> for Variants {
49    fn from(fields: Cow<'static, [TagTree]>) -> Self {
50        Self::new(fields)
51    }
52}
53
54impl core::ops::Deref for Variants {
55    type Target = [Tag];
56
57    fn deref(&self) -> &Self::Target {
58        &self.fields
59    }
60}