miden_assembly_syntax/ast/attribute/
meta.rs1mod expr;
2mod kv;
3mod list;
4
5use alloc::{collections::BTreeMap, string::String, sync::Arc, vec::Vec};
6use core::fmt;
7
8use miden_debug_types::{SourceSpan, Span};
9
10pub use self::{expr::MetaExpr, kv::MetaKeyValue, list::MetaList};
11use crate::{Felt, ast::Ident, parser::WordValue};
12
13#[derive(Clone, PartialEq, Eq)]
15pub enum Meta {
16 Unit,
18 List(Vec<MetaExpr>),
22 KeyValue(BTreeMap<Ident, MetaExpr>),
27}
28impl Meta {
29 #[inline]
33 pub fn borrow(&self) -> Option<BorrowedMeta<'_>> {
34 match self {
35 Self::Unit => None,
36 Self::List(list) => Some(BorrowedMeta::List(list)),
37 Self::KeyValue(kv) => Some(BorrowedMeta::KeyValue(kv)),
38 }
39 }
40}
41impl FromIterator<MetaItem> for Meta {
42 #[inline]
43 fn from_iter<T: IntoIterator<Item = MetaItem>>(iter: T) -> Self {
44 let mut iter = iter.into_iter();
45 match iter.next() {
46 None => Self::Unit,
47 Some(MetaItem::Expr(expr)) => Self::List(
48 core::iter::once(expr)
49 .chain(iter.map(|item| match item {
50 MetaItem::Expr(expr) => expr,
51 MetaItem::KeyValue(..) => unsafe { core::hint::unreachable_unchecked() },
52 }))
53 .collect(),
54 ),
55 Some(MetaItem::KeyValue(k, v)) => Self::KeyValue(
56 core::iter::once((k, v))
57 .chain(iter.map(|item| match item {
58 MetaItem::KeyValue(k, v) => (k, v),
59 MetaItem::Expr(_) => unsafe { core::hint::unreachable_unchecked() },
60 }))
61 .collect(),
62 ),
63 }
64 }
65}
66
67impl FromIterator<MetaExpr> for Meta {
68 #[inline]
69 fn from_iter<T: IntoIterator<Item = MetaExpr>>(iter: T) -> Self {
70 Self::List(iter.into_iter().collect())
71 }
72}
73
74impl FromIterator<(Ident, MetaExpr)> for Meta {
75 #[inline]
76 fn from_iter<T: IntoIterator<Item = (Ident, MetaExpr)>>(iter: T) -> Self {
77 Self::KeyValue(iter.into_iter().collect())
78 }
79}
80
81impl<'a> FromIterator<(&'a str, MetaExpr)> for Meta {
82 #[inline]
83 fn from_iter<T>(iter: T) -> Self
84 where
85 T: IntoIterator<Item = (&'a str, MetaExpr)>,
86 {
87 Self::KeyValue(
88 iter.into_iter()
89 .map(|(k, v)| {
90 let k = Ident::from_raw_parts(Span::new(SourceSpan::UNKNOWN, Arc::from(k)));
91 (k, v)
92 })
93 .collect(),
94 )
95 }
96}
97
98impl<I, V> From<I> for Meta
99where
100 Meta: FromIterator<V>,
101 I: IntoIterator<Item = V>,
102{
103 #[inline]
104 fn from(iter: I) -> Self {
105 Self::from_iter(iter)
106 }
107}
108
109#[derive(Copy, Clone, PartialEq, Eq)]
113pub enum BorrowedMeta<'a> {
114 List(&'a [MetaExpr]),
116 KeyValue(&'a BTreeMap<Ident, MetaExpr>),
118}
119impl fmt::Debug for BorrowedMeta<'_> {
120 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
121 match self {
122 Self::List(items) => write!(f, "{items:#?}"),
123 Self::KeyValue(items) => write!(f, "{items:#?}"),
124 }
125 }
126}
127
128#[derive(Clone, PartialEq, Eq)]
133pub enum MetaItem {
134 Expr(MetaExpr),
138 KeyValue(Ident, MetaExpr),
142}
143
144impl MetaItem {
145 #[inline]
149 #[track_caller]
150 pub fn unwrap_expr(self) -> MetaExpr {
151 match self {
152 Self::Expr(expr) => expr,
153 Self::KeyValue(..) => unreachable!("tried to unwrap key-value as expression"),
154 }
155 }
156
157 #[inline]
161 #[track_caller]
162 pub fn unwrap_key_value(self) -> (Ident, MetaExpr) {
163 match self {
164 Self::KeyValue(k, v) => (k, v),
165 Self::Expr(_) => unreachable!("tried to unwrap expression as key-value"),
166 }
167 }
168}
169
170impl From<Ident> for MetaItem {
171 fn from(value: Ident) -> Self {
172 Self::Expr(MetaExpr::Ident(value))
173 }
174}
175
176impl From<&str> for MetaItem {
177 fn from(value: &str) -> Self {
178 Self::Expr(MetaExpr::from(value))
179 }
180}
181
182impl From<String> for MetaItem {
183 fn from(value: String) -> Self {
184 Self::Expr(MetaExpr::from(value))
185 }
186}
187
188impl From<u8> for MetaItem {
189 fn from(value: u8) -> Self {
190 Self::Expr(MetaExpr::from(value))
191 }
192}
193
194impl From<u16> for MetaItem {
195 fn from(value: u16) -> Self {
196 Self::Expr(MetaExpr::from(value))
197 }
198}
199
200impl From<u32> for MetaItem {
201 fn from(value: u32) -> Self {
202 Self::Expr(MetaExpr::from(value))
203 }
204}
205
206impl From<Felt> for MetaItem {
207 fn from(value: Felt) -> Self {
208 Self::Expr(MetaExpr::from(value))
209 }
210}
211
212impl From<WordValue> for MetaItem {
213 fn from(value: WordValue) -> Self {
214 Self::Expr(MetaExpr::from(value))
215 }
216}
217
218impl<V> From<(Ident, V)> for MetaItem
219where
220 V: Into<MetaExpr>,
221{
222 fn from(entry: (Ident, V)) -> Self {
223 let (key, value) = entry;
224 Self::KeyValue(key, value.into())
225 }
226}
227
228impl<V> From<(&str, V)> for MetaItem
229where
230 V: Into<MetaExpr>,
231{
232 fn from(entry: (&str, V)) -> Self {
233 let (key, value) = entry;
234 let key = Ident::from_raw_parts(Span::new(SourceSpan::UNKNOWN, Arc::from(key)));
235 Self::KeyValue(key, value.into())
236 }
237}
238
239impl<V> From<(String, V)> for MetaItem
240where
241 V: Into<MetaExpr>,
242{
243 fn from(entry: (String, V)) -> Self {
244 let (key, value) = entry;
245 let key =
246 Ident::from_raw_parts(Span::new(SourceSpan::UNKNOWN, Arc::from(key.into_boxed_str())));
247 Self::KeyValue(key, value.into())
248 }
249}