toasty_core/stmt/
ty_union.rs1use super::Type;
2
3#[derive(Debug, Clone)]
9#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
10pub struct TypeUnion {
11 types: Vec<Type>,
13}
14
15impl TypeUnion {
16 pub fn new() -> Self {
26 Self { types: Vec::new() }
27 }
28
29 pub fn insert(&mut self, ty: Type) -> bool {
34 if matches!(ty, Type::Unknown) {
35 return false;
36 }
37 if self.types.contains(&ty) {
38 return false;
39 }
40 self.types.push(ty);
41 true
42 }
43
44 pub fn contains(&self, ty: &Type) -> bool {
46 self.types.contains(ty)
47 }
48
49 pub fn len(&self) -> usize {
51 self.types.len()
52 }
53
54 pub fn is_empty(&self) -> bool {
56 self.types.is_empty()
57 }
58
59 pub fn iter(&self) -> impl Iterator<Item = &Type> {
61 self.types.iter()
62 }
63
64 pub fn simplify(self) -> Type {
70 match self.types.len() {
71 0 => Type::Null,
72 1 => self.types.into_iter().next().unwrap(),
73 _ => Type::Union(self),
74 }
75 }
76}
77
78impl Default for TypeUnion {
79 fn default() -> Self {
80 Self::new()
81 }
82}
83
84impl PartialEq for TypeUnion {
87 fn eq(&self, other: &Self) -> bool {
88 self.types.len() == other.types.len() && self.types.iter().all(|t| other.types.contains(t))
89 }
90}
91
92impl Eq for TypeUnion {}
93
94impl IntoIterator for TypeUnion {
95 type Item = Type;
96 type IntoIter = std::vec::IntoIter<Type>;
97
98 fn into_iter(self) -> Self::IntoIter {
99 self.types.into_iter()
100 }
101}
102
103impl<'a> IntoIterator for &'a TypeUnion {
104 type Item = &'a Type;
105 type IntoIter = std::slice::Iter<'a, Type>;
106
107 fn into_iter(self) -> Self::IntoIter {
108 self.types.iter()
109 }
110}
111
112impl From<TypeUnion> for Type {
113 fn from(value: TypeUnion) -> Self {
114 Type::Union(value)
115 }
116}