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}