miden_assembly_syntax/ast/attribute/
set.rs1use alloc::vec::Vec;
2use core::fmt;
3
4#[cfg(feature = "serde")]
5use serde::{Deserialize, Serialize};
6
7use super::*;
8use crate::ast::Ident;
9
10#[derive(Default, Clone, PartialEq, Eq)]
18#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
19pub struct AttributeSet {
20 attrs: Vec<Attribute>,
31}
32
33impl AttributeSet {
34 pub fn new<I>(attrs: I) -> Self
39 where
40 I: IntoIterator<Item = Attribute>,
41 {
42 let mut this = Self { attrs: attrs.into_iter().collect() };
43 this.attrs.sort_by_key(|attr| attr.id());
44 this.attrs.dedup_by_key(|attr| attr.id());
45 this
46 }
47
48 #[inline]
50 pub fn is_empty(&self) -> bool {
51 self.attrs.is_empty()
52 }
53
54 #[inline]
56 pub fn len(&self) -> usize {
57 self.attrs.len()
58 }
59
60 pub fn has(&self, name: impl AsRef<str>) -> bool {
62 self.get(name).is_some()
63 }
64
65 pub fn get(&self, name: impl AsRef<str>) -> Option<&Attribute> {
67 let name = name.as_ref();
68 match self.attrs.binary_search_by_key(&name, |attr| attr.name()) {
69 Ok(index) => self.attrs.get(index),
70 Err(_) => None,
71 }
72 }
73
74 pub fn get_mut(&mut self, name: impl AsRef<str>) -> Option<&mut Attribute> {
76 let name = name.as_ref();
77 match self.attrs.binary_search_by_key(&name, |attr| attr.name()) {
78 Ok(index) => self.attrs.get_mut(index),
79 Err(_) => None,
80 }
81 }
82
83 #[inline]
85 pub fn iter(&self) -> core::slice::Iter<'_, Attribute> {
86 self.attrs.iter()
87 }
88
89 #[inline]
91 pub fn iter_mut(&mut self) -> core::slice::IterMut<'_, Attribute> {
92 self.attrs.iter_mut()
93 }
94
95 pub fn insert(&mut self, attr: Attribute) -> bool {
99 let name = attr.name();
100 match self.attrs.binary_search_by_key(&name, |attr| attr.name()) {
101 Ok(index) => {
102 self.attrs[index] = attr;
104 false
105 },
106 Err(index) => {
107 self.attrs.insert(index, attr);
108 true
109 },
110 }
111 }
112
113 pub fn insert_new(&mut self, attr: Attribute) -> Result<(), Attribute> {
118 if self.has(attr.name()) {
119 Err(attr)
120 } else {
121 self.insert(attr);
122 Ok(())
123 }
124 }
125
126 pub fn remove(&mut self, name: impl AsRef<str>) -> Option<Attribute> {
128 let name = name.as_ref();
129 match self.attrs.binary_search_by_key(&name, |attr| attr.name()) {
130 Ok(index) => Some(self.attrs.remove(index)),
131 Err(_) => None,
132 }
133 }
134
135 pub fn entry(&mut self, key: Ident) -> AttributeSetEntry<'_> {
137 match self.attrs.binary_search_by_key(&key.as_str(), |attr| attr.name()) {
138 Ok(index) => AttributeSetEntry::occupied(self, index),
139 Err(index) => AttributeSetEntry::vacant(self, key, index),
140 }
141 }
142
143 #[inline]
145 pub fn clear(&mut self) {
146 self.attrs.clear();
147 }
148}
149
150impl fmt::Debug for AttributeSet {
151 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
152 let mut builder = f.debug_map();
153 for attr in self.iter() {
154 match attr.metadata() {
155 None => {
156 builder.entry(&attr.name(), &"None");
157 },
158 Some(meta) => {
159 builder.entry(&attr.name(), &meta);
160 },
161 }
162 }
163 builder.finish()
164 }
165}
166
167impl FromIterator<Attribute> for AttributeSet {
168 #[inline]
169 fn from_iter<T: IntoIterator<Item = Attribute>>(iter: T) -> Self {
170 Self::new(iter)
171 }
172}
173
174impl Extend<Attribute> for AttributeSet {
175 fn extend<T: IntoIterator<Item = Attribute>>(&mut self, iter: T) {
176 for attr in iter {
177 self.insert(attr);
178 }
179 }
180}
181
182pub enum AttributeSetEntry<'a> {
184 Occupied(AttributeSetOccupiedEntry<'a>),
186 Vacant(AttributeSetVacantEntry<'a>),
188}
189impl<'a> AttributeSetEntry<'a> {
190 fn occupied(set: &'a mut AttributeSet, index: usize) -> Self {
191 Self::Occupied(AttributeSetOccupiedEntry { set, index })
192 }
193
194 fn vacant(set: &'a mut AttributeSet, key: Ident, index: usize) -> Self {
195 Self::Vacant(AttributeSetVacantEntry { set, key, index })
196 }
197}
198
199#[doc(hidden)]
200pub struct AttributeSetOccupiedEntry<'a> {
201 set: &'a mut AttributeSet,
202 index: usize,
203}
204impl AttributeSetOccupiedEntry<'_> {
205 #[inline]
206 pub fn get(&self) -> &Attribute {
207 &self.set.attrs[self.index]
208 }
209
210 #[inline]
211 pub fn get_mut(&mut self) -> &mut Attribute {
212 &mut self.set.attrs[self.index]
213 }
214
215 pub fn insert(self, attr: Attribute) {
216 if attr.name() != self.get().name() {
217 self.set.insert(attr);
218 } else {
219 self.set.attrs[self.index] = attr;
220 }
221 }
222
223 #[inline]
224 pub fn remove(self) -> Attribute {
225 self.set.attrs.remove(self.index)
226 }
227}
228
229#[doc(hidden)]
230pub struct AttributeSetVacantEntry<'a> {
231 set: &'a mut AttributeSet,
232 key: Ident,
233 index: usize,
234}
235impl AttributeSetVacantEntry<'_> {
236 pub fn insert(self, attr: Attribute) {
237 if self.key != attr.id() {
238 self.set.insert(attr);
239 } else {
240 self.set.attrs.insert(self.index, attr);
241 }
242 }
243}
244
245#[cfg(feature = "arbitrary")]
246impl proptest::arbitrary::Arbitrary for AttributeSet {
247 type Parameters = ();
248
249 fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
250 use proptest::{arbitrary::any, strategy::Strategy};
251
252 let items = proptest::collection::vec(any::<Attribute>(), 1..3);
253 items.prop_map(|attrs| Self { attrs }).boxed()
254 }
255
256 type Strategy = proptest::prelude::BoxedStrategy<Self>;
257}
258
259impl Serializable for AttributeSet {
260 fn write_into<W: ByteWriter>(&self, target: &mut W) {
261 self.attrs.write_into(target)
262 }
263}
264
265impl Deserializable for AttributeSet {
266 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
267 let attrs = Vec::read_from(source)?;
268 Ok(Self { attrs })
269 }
270}