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))]
19#[cfg_attr(
20 all(feature = "arbitrary", test),
21 miden_test_serde_macros::serde_test(winter_serde(true))
22)]
23pub struct AttributeSet {
24 attrs: Vec<Attribute>,
35}
36
37impl AttributeSet {
38 pub fn new<I>(attrs: I) -> Self
43 where
44 I: IntoIterator<Item = Attribute>,
45 {
46 let mut this = Self { attrs: attrs.into_iter().collect() };
47 this.attrs.sort_by_key(|attr| attr.id());
48 this.attrs.dedup_by_key(|attr| attr.id());
49 this
50 }
51
52 #[inline]
54 pub fn is_empty(&self) -> bool {
55 self.attrs.is_empty()
56 }
57
58 #[inline]
60 pub fn len(&self) -> usize {
61 self.attrs.len()
62 }
63
64 pub fn has(&self, name: impl AsRef<str>) -> bool {
66 self.get(name).is_some()
67 }
68
69 pub fn get(&self, name: impl AsRef<str>) -> Option<&Attribute> {
71 let name = name.as_ref();
72 match self.attrs.binary_search_by_key(&name, |attr| attr.name()) {
73 Ok(index) => self.attrs.get(index),
74 Err(_) => None,
75 }
76 }
77
78 pub fn get_mut(&mut self, name: impl AsRef<str>) -> Option<&mut Attribute> {
80 let name = name.as_ref();
81 match self.attrs.binary_search_by_key(&name, |attr| attr.name()) {
82 Ok(index) => self.attrs.get_mut(index),
83 Err(_) => None,
84 }
85 }
86
87 #[inline]
89 pub fn iter(&self) -> core::slice::Iter<'_, Attribute> {
90 self.attrs.iter()
91 }
92
93 #[inline]
95 pub fn iter_mut(&mut self) -> core::slice::IterMut<'_, Attribute> {
96 self.attrs.iter_mut()
97 }
98
99 pub fn insert(&mut self, attr: Attribute) -> bool {
103 let name = attr.name();
104 match self.attrs.binary_search_by_key(&name, |attr| attr.name()) {
105 Ok(index) => {
106 self.attrs[index] = attr;
108 false
109 },
110 Err(index) => {
111 self.attrs.insert(index, attr);
112 true
113 },
114 }
115 }
116
117 pub fn insert_new(&mut self, attr: Attribute) -> Result<(), Attribute> {
122 if self.has(attr.name()) {
123 Err(attr)
124 } else {
125 self.insert(attr);
126 Ok(())
127 }
128 }
129
130 pub fn remove(&mut self, name: impl AsRef<str>) -> Option<Attribute> {
132 let name = name.as_ref();
133 match self.attrs.binary_search_by_key(&name, |attr| attr.name()) {
134 Ok(index) => Some(self.attrs.remove(index)),
135 Err(_) => None,
136 }
137 }
138
139 pub fn entry(&mut self, key: Ident) -> AttributeSetEntry<'_> {
141 match self.attrs.binary_search_by_key(&key.as_str(), |attr| attr.name()) {
142 Ok(index) => AttributeSetEntry::occupied(self, index),
143 Err(index) => AttributeSetEntry::vacant(self, key, index),
144 }
145 }
146
147 #[inline]
149 pub fn clear(&mut self) {
150 self.attrs.clear();
151 }
152}
153
154impl fmt::Debug for AttributeSet {
155 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
156 let mut builder = f.debug_map();
157 for attr in self.iter() {
158 match attr.metadata() {
159 None => {
160 builder.entry(&attr.name(), &"None");
161 },
162 Some(meta) => {
163 builder.entry(&attr.name(), &meta);
164 },
165 }
166 }
167 builder.finish()
168 }
169}
170
171impl FromIterator<Attribute> for AttributeSet {
172 #[inline]
173 fn from_iter<T: IntoIterator<Item = Attribute>>(iter: T) -> Self {
174 Self::new(iter)
175 }
176}
177
178impl Extend<Attribute> for AttributeSet {
179 fn extend<T: IntoIterator<Item = Attribute>>(&mut self, iter: T) {
180 for attr in iter {
181 self.insert(attr);
182 }
183 }
184}
185
186pub enum AttributeSetEntry<'a> {
188 Occupied(AttributeSetOccupiedEntry<'a>),
190 Vacant(AttributeSetVacantEntry<'a>),
192}
193impl<'a> AttributeSetEntry<'a> {
194 fn occupied(set: &'a mut AttributeSet, index: usize) -> Self {
195 Self::Occupied(AttributeSetOccupiedEntry { set, index })
196 }
197
198 fn vacant(set: &'a mut AttributeSet, key: Ident, index: usize) -> Self {
199 Self::Vacant(AttributeSetVacantEntry { set, key, index })
200 }
201}
202
203#[doc(hidden)]
204pub struct AttributeSetOccupiedEntry<'a> {
205 set: &'a mut AttributeSet,
206 index: usize,
207}
208impl AttributeSetOccupiedEntry<'_> {
209 #[inline]
210 pub fn get(&self) -> &Attribute {
211 &self.set.attrs[self.index]
212 }
213
214 #[inline]
215 pub fn get_mut(&mut self) -> &mut Attribute {
216 &mut self.set.attrs[self.index]
217 }
218
219 pub fn insert(self, attr: Attribute) {
220 if attr.name() != self.get().name() {
221 self.set.insert(attr);
222 } else {
223 self.set.attrs[self.index] = attr;
224 }
225 }
226
227 #[inline]
228 pub fn remove(self) -> Attribute {
229 self.set.attrs.remove(self.index)
230 }
231}
232
233#[doc(hidden)]
234pub struct AttributeSetVacantEntry<'a> {
235 set: &'a mut AttributeSet,
236 key: Ident,
237 index: usize,
238}
239impl AttributeSetVacantEntry<'_> {
240 pub fn insert(self, attr: Attribute) {
241 if self.key != attr.id() {
242 self.set.insert(attr);
243 } else {
244 self.set.attrs.insert(self.index, attr);
245 }
246 }
247}
248
249#[cfg(feature = "arbitrary")]
250impl proptest::arbitrary::Arbitrary for AttributeSet {
251 type Parameters = ();
252
253 fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
254 use proptest::{arbitrary::any, strategy::Strategy};
255
256 let items = proptest::collection::vec(any::<Attribute>(), 1..3);
257 items.prop_map(|attrs| Self { attrs }).boxed()
258 }
259
260 type Strategy = proptest::prelude::BoxedStrategy<Self>;
261}
262
263impl Serializable for AttributeSet {
264 fn write_into<W: ByteWriter>(&self, target: &mut W) {
265 self.attrs.write_into(target)
266 }
267}
268
269impl Deserializable for AttributeSet {
270 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
271 let attrs = Vec::read_from(source)?;
272 Ok(Self { attrs })
273 }
274}