miden_assembly_syntax/ast/attribute/
set.rs1use alloc::vec::Vec;
2use core::fmt;
3
4use super::*;
5use crate::ast::Ident;
6
7#[derive(Default, Clone, PartialEq, Eq)]
15pub struct AttributeSet {
16 attrs: Vec<Attribute>,
27}
28
29impl AttributeSet {
30 pub fn new<I>(attrs: I) -> Self
35 where
36 I: IntoIterator<Item = Attribute>,
37 {
38 let mut this = Self { attrs: attrs.into_iter().collect() };
39 this.attrs.sort_by_key(|attr| attr.id());
40 this.attrs.dedup_by_key(|attr| attr.id());
41 this
42 }
43
44 #[inline]
46 pub fn is_empty(&self) -> bool {
47 self.attrs.is_empty()
48 }
49
50 #[inline]
52 pub fn len(&self) -> usize {
53 self.attrs.len()
54 }
55
56 pub fn has(&self, name: impl AsRef<str>) -> bool {
58 self.get(name).is_some()
59 }
60
61 pub fn get(&self, name: impl AsRef<str>) -> Option<&Attribute> {
63 let name = name.as_ref();
64 match self.attrs.binary_search_by_key(&name, |attr| attr.name()) {
65 Ok(index) => self.attrs.get(index),
66 Err(_) => None,
67 }
68 }
69
70 pub fn get_mut(&mut self, name: impl AsRef<str>) -> Option<&mut Attribute> {
72 let name = name.as_ref();
73 match self.attrs.binary_search_by_key(&name, |attr| attr.name()) {
74 Ok(index) => self.attrs.get_mut(index),
75 Err(_) => None,
76 }
77 }
78
79 #[inline]
81 pub fn iter(&self) -> core::slice::Iter<'_, Attribute> {
82 self.attrs.iter()
83 }
84
85 #[inline]
87 pub fn iter_mut(&mut self) -> core::slice::IterMut<'_, Attribute> {
88 self.attrs.iter_mut()
89 }
90
91 pub fn insert(&mut self, attr: Attribute) -> bool {
95 let name = attr.name();
96 match self.attrs.binary_search_by_key(&name, |attr| attr.name()) {
97 Ok(index) => {
98 self.attrs[index] = attr;
100 false
101 },
102 Err(index) => {
103 self.attrs.insert(index, attr);
104 true
105 },
106 }
107 }
108
109 pub fn insert_new(&mut self, attr: Attribute) -> Result<(), Attribute> {
114 if self.has(attr.name()) {
115 Err(attr)
116 } else {
117 self.insert(attr);
118 Ok(())
119 }
120 }
121
122 pub fn remove(&mut self, name: impl AsRef<str>) -> Option<Attribute> {
124 let name = name.as_ref();
125 match self.attrs.binary_search_by_key(&name, |attr| attr.name()) {
126 Ok(index) => Some(self.attrs.remove(index)),
127 Err(_) => None,
128 }
129 }
130
131 pub fn entry(&mut self, key: Ident) -> AttributeSetEntry<'_> {
133 match self.attrs.binary_search_by_key(&key.as_str(), |attr| attr.name()) {
134 Ok(index) => AttributeSetEntry::occupied(self, index),
135 Err(index) => AttributeSetEntry::vacant(self, key, index),
136 }
137 }
138
139 #[inline]
141 pub fn clear(&mut self) {
142 self.attrs.clear();
143 }
144}
145
146impl fmt::Debug for AttributeSet {
147 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
148 let mut builder = f.debug_map();
149 for attr in self.iter() {
150 match attr.metadata() {
151 None => {
152 builder.entry(&attr.name(), &"None");
153 },
154 Some(meta) => {
155 builder.entry(&attr.name(), &meta);
156 },
157 }
158 }
159 builder.finish()
160 }
161}
162
163impl FromIterator<Attribute> for AttributeSet {
164 #[inline]
165 fn from_iter<T: IntoIterator<Item = Attribute>>(iter: T) -> Self {
166 Self::new(iter)
167 }
168}
169
170impl Extend<Attribute> for AttributeSet {
171 fn extend<T: IntoIterator<Item = Attribute>>(&mut self, iter: T) {
172 for attr in iter {
173 self.insert(attr);
174 }
175 }
176}
177
178pub enum AttributeSetEntry<'a> {
180 Occupied(AttributeSetOccupiedEntry<'a>),
182 Vacant(AttributeSetVacantEntry<'a>),
184}
185impl<'a> AttributeSetEntry<'a> {
186 fn occupied(set: &'a mut AttributeSet, index: usize) -> Self {
187 Self::Occupied(AttributeSetOccupiedEntry { set, index })
188 }
189
190 fn vacant(set: &'a mut AttributeSet, key: Ident, index: usize) -> Self {
191 Self::Vacant(AttributeSetVacantEntry { set, key, index })
192 }
193}
194
195#[doc(hidden)]
196pub struct AttributeSetOccupiedEntry<'a> {
197 set: &'a mut AttributeSet,
198 index: usize,
199}
200impl AttributeSetOccupiedEntry<'_> {
201 #[inline]
202 pub fn get(&self) -> &Attribute {
203 &self.set.attrs[self.index]
204 }
205
206 #[inline]
207 pub fn get_mut(&mut self) -> &mut Attribute {
208 &mut self.set.attrs[self.index]
209 }
210
211 pub fn insert(self, attr: Attribute) {
212 if attr.name() != self.get().name() {
213 self.set.insert(attr);
214 } else {
215 self.set.attrs[self.index] = attr;
216 }
217 }
218
219 #[inline]
220 pub fn remove(self) -> Attribute {
221 self.set.attrs.remove(self.index)
222 }
223}
224
225#[doc(hidden)]
226pub struct AttributeSetVacantEntry<'a> {
227 set: &'a mut AttributeSet,
228 key: Ident,
229 index: usize,
230}
231impl AttributeSetVacantEntry<'_> {
232 pub fn insert(self, attr: Attribute) {
233 if self.key != attr.id() {
234 self.set.insert(attr);
235 } else {
236 self.set.attrs.insert(self.index, attr);
237 }
238 }
239}