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::{
12 Felt,
13 ast::Ident,
14 parser::{IntValue, WordValue},
15};
16
17#[derive(Clone, PartialEq, Eq)]
19pub enum Meta {
20 Unit,
22 List(Vec<MetaExpr>),
26 KeyValue(BTreeMap<Ident, MetaExpr>),
31}
32impl Meta {
33 #[inline]
37 pub fn borrow(&self) -> Option<BorrowedMeta<'_>> {
38 match self {
39 Self::Unit => None,
40 Self::List(list) => Some(BorrowedMeta::List(list)),
41 Self::KeyValue(kv) => Some(BorrowedMeta::KeyValue(kv)),
42 }
43 }
44}
45impl FromIterator<MetaItem> for Meta {
46 #[inline]
47 fn from_iter<T: IntoIterator<Item = MetaItem>>(iter: T) -> Self {
48 let mut iter = iter.into_iter();
49 match iter.next() {
50 None => Self::Unit,
51 Some(MetaItem::Expr(expr)) => Self::List(
52 core::iter::once(expr)
53 .chain(iter.map(|item| match item {
54 MetaItem::Expr(expr) => expr,
55 MetaItem::KeyValue(..) => unsafe { core::hint::unreachable_unchecked() },
56 }))
57 .collect(),
58 ),
59 Some(MetaItem::KeyValue(k, v)) => Self::KeyValue(
60 core::iter::once((k, v))
61 .chain(iter.map(|item| match item {
62 MetaItem::KeyValue(k, v) => (k, v),
63 MetaItem::Expr(_) => unsafe { core::hint::unreachable_unchecked() },
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::String(Ident::from_raw_parts(Span::new(
183 SourceSpan::UNKNOWN,
184 Arc::from(value),
185 ))))
186 }
187}
188
189impl From<String> for MetaItem {
190 fn from(value: String) -> Self {
191 Self::Expr(MetaExpr::String(Ident::from_raw_parts(Span::new(
192 SourceSpan::UNKNOWN,
193 Arc::from(value.into_boxed_str()),
194 ))))
195 }
196}
197
198impl From<u8> for MetaItem {
199 fn from(value: u8) -> Self {
200 Self::Expr(MetaExpr::Int(Span::new(SourceSpan::UNKNOWN, IntValue::U8(value))))
201 }
202}
203
204impl From<u16> for MetaItem {
205 fn from(value: u16) -> Self {
206 Self::Expr(MetaExpr::Int(Span::new(SourceSpan::UNKNOWN, IntValue::U16(value))))
207 }
208}
209
210impl From<u32> for MetaItem {
211 fn from(value: u32) -> Self {
212 Self::Expr(MetaExpr::Int(Span::new(SourceSpan::UNKNOWN, IntValue::U32(value))))
213 }
214}
215
216impl From<Felt> for MetaItem {
217 fn from(value: Felt) -> Self {
218 Self::Expr(MetaExpr::Int(Span::new(SourceSpan::UNKNOWN, IntValue::Felt(value))))
219 }
220}
221
222impl From<WordValue> for MetaItem {
223 fn from(value: WordValue) -> Self {
224 Self::Expr(MetaExpr::Int(Span::new(SourceSpan::UNKNOWN, IntValue::Word(value))))
225 }
226}
227
228impl<V> From<(Ident, V)> for MetaItem
229where
230 V: Into<MetaExpr>,
231{
232 fn from(entry: (Ident, V)) -> Self {
233 let (key, value) = entry;
234 Self::KeyValue(key, value.into())
235 }
236}
237
238impl<V> From<(&str, V)> for MetaItem
239where
240 V: Into<MetaExpr>,
241{
242 fn from(entry: (&str, V)) -> Self {
243 let (key, value) = entry;
244 let key = Ident::from_raw_parts(Span::new(SourceSpan::UNKNOWN, Arc::from(key)));
245 Self::KeyValue(key, value.into())
246 }
247}
248
249impl<V> From<(String, V)> for MetaItem
250where
251 V: Into<MetaExpr>,
252{
253 fn from(entry: (String, V)) -> Self {
254 let (key, value) = entry;
255 let key =
256 Ident::from_raw_parts(Span::new(SourceSpan::UNKNOWN, Arc::from(key.into_boxed_str())));
257 Self::KeyValue(key, value.into())
258 }
259}