miden_assembly_syntax/ast/attribute/meta/
list.rs1use alloc::vec::Vec;
2
3use miden_core::utils::{
4 ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable,
5};
6use miden_debug_types::{SourceSpan, Spanned};
7#[cfg(feature = "serde")]
8use serde::{Deserialize, Serialize};
9
10use super::MetaExpr;
11use crate::ast::Ident;
12
13#[derive(Debug, Clone)]
15#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
16pub struct MetaList {
17 #[cfg_attr(feature = "serde", serde(skip, default))]
18 pub span: SourceSpan,
19 pub name: Ident,
21 pub items: Vec<MetaExpr>,
24}
25
26impl Spanned for MetaList {
27 #[inline(always)]
28 fn span(&self) -> SourceSpan {
29 self.span
30 }
31}
32
33impl MetaList {
34 pub fn new<I>(name: Ident, items: I) -> Self
35 where
36 I: IntoIterator<Item = MetaExpr>,
37 {
38 Self {
39 span: SourceSpan::default(),
40 name,
41 items: items.into_iter().collect(),
42 }
43 }
44
45 pub fn with_span(mut self, span: SourceSpan) -> Self {
46 self.span = span;
47 self
48 }
49
50 pub fn name(&self) -> &str {
52 self.name.as_str()
53 }
54
55 pub fn id(&self) -> Ident {
57 self.name.clone()
58 }
59
60 #[inline]
62 pub fn is_empty(&self) -> bool {
63 self.items.is_empty()
64 }
65
66 #[inline]
68 pub fn len(&self) -> usize {
69 self.items.len()
70 }
71
72 #[inline]
74 pub fn as_slice(&self) -> &[MetaExpr] {
75 self.items.as_slice()
76 }
77
78 #[inline]
80 pub fn as_mut_slice(&mut self) -> &mut [MetaExpr] {
81 self.items.as_mut_slice()
82 }
83}
84
85impl Eq for MetaList {}
86
87impl PartialEq for MetaList {
88 fn eq(&self, other: &Self) -> bool {
89 self.name == other.name && self.items == other.items
90 }
91}
92
93impl PartialOrd for MetaList {
94 #[inline]
95 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
96 Some(self.cmp(other))
97 }
98}
99
100impl Ord for MetaList {
101 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
102 self.name.cmp(&other.name).then_with(|| self.items.cmp(&other.items))
103 }
104}
105
106impl core::hash::Hash for MetaList {
107 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
108 self.name.hash(state);
109 self.items.hash(state);
110 }
111}
112
113#[cfg(feature = "arbitrary")]
114impl proptest::arbitrary::Arbitrary for MetaList {
115 type Parameters = ();
116
117 fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
118 use proptest::{arbitrary::any, strategy::Strategy};
119
120 let name = any::<Ident>();
121 let items = proptest::collection::vec(any::<MetaExpr>(), 1..3);
122 (name, items)
123 .prop_map(|(name, items)| Self { span: SourceSpan::UNKNOWN, name, items })
124 .boxed()
125 }
126
127 type Strategy = proptest::prelude::BoxedStrategy<Self>;
128}
129
130impl Serializable for MetaList {
131 fn write_into<W: ByteWriter>(&self, target: &mut W) {
132 self.name.write_into(target);
133 self.items.write_into(target);
134 }
135}
136
137impl Deserializable for MetaList {
138 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
139 let name = Ident::read_from(source)?;
140 let items = Vec::read_from(source)?;
141
142 Ok(Self { span: SourceSpan::UNKNOWN, name, items })
143 }
144}