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(..) => {
52 unreachable!("mixed MetaItem variants in iterator: expected Expr")
53 },
54 }))
55 .collect(),
56 ),
57 Some(MetaItem::KeyValue(k, v)) => Self::KeyValue(
58 core::iter::once((k, v))
59 .chain(iter.map(|item| match item {
60 MetaItem::KeyValue(k, v) => (k, v),
61 MetaItem::Expr(_) => {
62 unreachable!("mixed MetaItem variants in iterator: expected KeyValue")
63 },
64 }))
65 .collect(),
66 ),
67 }
68 }
69}
70
71impl FromIterator<MetaExpr> for Meta {
72 #[inline]
73 fn from_iter<T: IntoIterator<Item = MetaExpr>>(iter: T) -> Self {
74 Self::List(iter.into_iter().collect())
75 }
76}
77
78impl FromIterator<(Ident, MetaExpr)> for Meta {
79 #[inline]
80 fn from_iter<T: IntoIterator<Item = (Ident, MetaExpr)>>(iter: T) -> Self {
81 Self::KeyValue(iter.into_iter().collect())
82 }
83}
84
85impl<'a> FromIterator<(&'a str, MetaExpr)> for Meta {
86 #[inline]
87 fn from_iter<T>(iter: T) -> Self
88 where
89 T: IntoIterator<Item = (&'a str, MetaExpr)>,
90 {
91 Self::KeyValue(
92 iter.into_iter()
93 .map(|(k, v)| {
94 let k = Ident::from_raw_parts(Span::new(SourceSpan::UNKNOWN, Arc::from(k)));
95 (k, v)
96 })
97 .collect(),
98 )
99 }
100}
101
102impl<I, V> From<I> for Meta
103where
104 Meta: FromIterator<V>,
105 I: IntoIterator<Item = V>,
106{
107 #[inline]
108 fn from(iter: I) -> Self {
109 Self::from_iter(iter)
110 }
111}
112
113#[derive(Copy, Clone, PartialEq, Eq)]
117pub enum BorrowedMeta<'a> {
118 List(&'a [MetaExpr]),
120 KeyValue(&'a BTreeMap<Ident, MetaExpr>),
122}
123impl fmt::Debug for BorrowedMeta<'_> {
124 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
125 match self {
126 Self::List(items) => write!(f, "{items:#?}"),
127 Self::KeyValue(items) => write!(f, "{items:#?}"),
128 }
129 }
130}
131
132#[derive(Clone, PartialEq, Eq)]
137pub enum MetaItem {
138 Expr(MetaExpr),
142 KeyValue(Ident, MetaExpr),
146}
147
148impl MetaItem {
149 #[inline]
153 #[track_caller]
154 pub fn unwrap_expr(self) -> MetaExpr {
155 match self {
156 Self::Expr(expr) => expr,
157 Self::KeyValue(..) => unreachable!("tried to unwrap key-value as expression"),
158 }
159 }
160
161 #[inline]
165 #[track_caller]
166 pub fn unwrap_key_value(self) -> (Ident, MetaExpr) {
167 match self {
168 Self::KeyValue(k, v) => (k, v),
169 Self::Expr(_) => unreachable!("tried to unwrap expression as key-value"),
170 }
171 }
172}
173
174impl From<Ident> for MetaItem {
175 fn from(value: Ident) -> Self {
176 Self::Expr(MetaExpr::Ident(value))
177 }
178}
179
180impl From<&str> for MetaItem {
181 fn from(value: &str) -> Self {
182 Self::Expr(MetaExpr::from(value))
183 }
184}
185
186impl From<String> for MetaItem {
187 fn from(value: String) -> Self {
188 Self::Expr(MetaExpr::from(value))
189 }
190}
191
192impl From<u8> for MetaItem {
193 fn from(value: u8) -> Self {
194 Self::Expr(MetaExpr::from(value))
195 }
196}
197
198impl From<u16> for MetaItem {
199 fn from(value: u16) -> Self {
200 Self::Expr(MetaExpr::from(value))
201 }
202}
203
204impl From<u32> for MetaItem {
205 fn from(value: u32) -> Self {
206 Self::Expr(MetaExpr::from(value))
207 }
208}
209
210impl From<Felt> for MetaItem {
211 fn from(value: Felt) -> Self {
212 Self::Expr(MetaExpr::from(value))
213 }
214}
215
216impl From<WordValue> for MetaItem {
217 fn from(value: WordValue) -> Self {
218 Self::Expr(MetaExpr::from(value))
219 }
220}
221
222impl<V> From<(Ident, V)> for MetaItem
223where
224 V: Into<MetaExpr>,
225{
226 fn from(entry: (Ident, V)) -> Self {
227 let (key, value) = entry;
228 Self::KeyValue(key, value.into())
229 }
230}
231
232impl<V> From<(&str, V)> for MetaItem
233where
234 V: Into<MetaExpr>,
235{
236 fn from(entry: (&str, V)) -> Self {
237 let (key, value) = entry;
238 let key = Ident::from_raw_parts(Span::new(SourceSpan::UNKNOWN, Arc::from(key)));
239 Self::KeyValue(key, value.into())
240 }
241}
242
243impl<V> From<(String, V)> for MetaItem
244where
245 V: Into<MetaExpr>,
246{
247 fn from(entry: (String, V)) -> Self {
248 let (key, value) = entry;
249 let key =
250 Ident::from_raw_parts(Span::new(SourceSpan::UNKNOWN, Arc::from(key.into_boxed_str())));
251 Self::KeyValue(key, value.into())
252 }
253}