miden_assembly/ast/attribute/
meta.rs1mod expr;
2mod kv;
3mod list;
4
5use alloc::{collections::BTreeMap, string::String, sync::Arc, vec::Vec};
6use core::fmt;
7
8pub use self::{expr::MetaExpr, kv::MetaKeyValue, list::MetaList};
9use crate::{Felt, SourceSpan, Span, ast::Ident, parser::HexEncodedValue};
10
11#[derive(Clone, PartialEq, Eq)]
13pub enum Meta {
14 Unit,
16 List(Vec<MetaExpr>),
20 KeyValue(BTreeMap<Ident, MetaExpr>),
25}
26impl Meta {
27 #[inline]
31 pub fn borrow(&self) -> Option<BorrowedMeta<'_>> {
32 match self {
33 Self::Unit => None,
34 Self::List(list) => Some(BorrowedMeta::List(list)),
35 Self::KeyValue(kv) => Some(BorrowedMeta::KeyValue(kv)),
36 }
37 }
38}
39impl FromIterator<MetaItem> for Meta {
40 #[inline]
41 fn from_iter<T: IntoIterator<Item = MetaItem>>(iter: T) -> Self {
42 let mut iter = iter.into_iter();
43 match iter.next() {
44 None => Self::Unit,
45 Some(MetaItem::Expr(expr)) => Self::List(
46 core::iter::once(expr)
47 .chain(iter.map(|item| match item {
48 MetaItem::Expr(expr) => expr,
49 MetaItem::KeyValue(..) => unsafe { core::hint::unreachable_unchecked() },
50 }))
51 .collect(),
52 ),
53 Some(MetaItem::KeyValue(k, v)) => Self::KeyValue(
54 core::iter::once((k, v))
55 .chain(iter.map(|item| match item {
56 MetaItem::KeyValue(k, v) => (k, v),
57 MetaItem::Expr(_) => unsafe { core::hint::unreachable_unchecked() },
58 }))
59 .collect(),
60 ),
61 }
62 }
63}
64
65impl FromIterator<MetaExpr> for Meta {
66 #[inline]
67 fn from_iter<T: IntoIterator<Item = MetaExpr>>(iter: T) -> Self {
68 Self::List(iter.into_iter().collect())
69 }
70}
71
72impl FromIterator<(Ident, MetaExpr)> for Meta {
73 #[inline]
74 fn from_iter<T: IntoIterator<Item = (Ident, MetaExpr)>>(iter: T) -> Self {
75 Self::KeyValue(iter.into_iter().collect())
76 }
77}
78
79impl<'a> FromIterator<(&'a str, MetaExpr)> for Meta {
80 #[inline]
81 fn from_iter<T>(iter: T) -> Self
82 where
83 T: IntoIterator<Item = (&'a str, MetaExpr)>,
84 {
85 Self::KeyValue(
86 iter.into_iter()
87 .map(|(k, v)| {
88 let k = Ident::from_raw_parts(Span::new(SourceSpan::UNKNOWN, Arc::from(k)));
89 (k, v)
90 })
91 .collect(),
92 )
93 }
94}
95
96impl<I, V> From<I> for Meta
97where
98 Meta: FromIterator<V>,
99 I: IntoIterator<Item = V>,
100{
101 #[inline]
102 fn from(iter: I) -> Self {
103 Self::from_iter(iter)
104 }
105}
106
107#[derive(Copy, Clone, PartialEq, Eq)]
111pub enum BorrowedMeta<'a> {
112 List(&'a [MetaExpr]),
114 KeyValue(&'a BTreeMap<Ident, MetaExpr>),
116}
117impl fmt::Debug for BorrowedMeta<'_> {
118 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
119 match self {
120 Self::List(items) => write!(f, "{items:#?}"),
121 Self::KeyValue(items) => write!(f, "{items:#?}"),
122 }
123 }
124}
125
126#[derive(Clone, PartialEq, Eq)]
131pub enum MetaItem {
132 Expr(MetaExpr),
136 KeyValue(Ident, MetaExpr),
140}
141
142impl MetaItem {
143 #[inline]
147 #[track_caller]
148 pub fn unwrap_expr(self) -> MetaExpr {
149 match self {
150 Self::Expr(expr) => expr,
151 Self::KeyValue(..) => unreachable!("tried to unwrap key-value as expression"),
152 }
153 }
154
155 #[inline]
159 #[track_caller]
160 pub fn unwrap_key_value(self) -> (Ident, MetaExpr) {
161 match self {
162 Self::KeyValue(k, v) => (k, v),
163 Self::Expr(_) => unreachable!("tried to unwrap expression as key-value"),
164 }
165 }
166}
167
168impl From<Ident> for MetaItem {
169 fn from(value: Ident) -> Self {
170 Self::Expr(MetaExpr::Ident(value))
171 }
172}
173
174impl From<&str> for MetaItem {
175 fn from(value: &str) -> Self {
176 Self::Expr(MetaExpr::String(Ident::from_raw_parts(Span::new(
177 SourceSpan::UNKNOWN,
178 Arc::from(value),
179 ))))
180 }
181}
182
183impl From<String> for MetaItem {
184 fn from(value: String) -> Self {
185 Self::Expr(MetaExpr::String(Ident::from_raw_parts(Span::new(
186 SourceSpan::UNKNOWN,
187 Arc::from(value.into_boxed_str()),
188 ))))
189 }
190}
191
192impl From<u8> for MetaItem {
193 fn from(value: u8) -> Self {
194 Self::Expr(MetaExpr::Int(Span::new(SourceSpan::UNKNOWN, HexEncodedValue::U8(value))))
195 }
196}
197
198impl From<u16> for MetaItem {
199 fn from(value: u16) -> Self {
200 Self::Expr(MetaExpr::Int(Span::new(SourceSpan::UNKNOWN, HexEncodedValue::U16(value))))
201 }
202}
203
204impl From<u32> for MetaItem {
205 fn from(value: u32) -> Self {
206 Self::Expr(MetaExpr::Int(Span::new(SourceSpan::UNKNOWN, HexEncodedValue::U32(value))))
207 }
208}
209
210impl From<Felt> for MetaItem {
211 fn from(value: Felt) -> Self {
212 Self::Expr(MetaExpr::Int(Span::new(SourceSpan::UNKNOWN, HexEncodedValue::Felt(value))))
213 }
214}
215
216impl From<[Felt; 4]> for MetaItem {
217 fn from(value: [Felt; 4]) -> Self {
218 Self::Expr(MetaExpr::Int(Span::new(SourceSpan::UNKNOWN, HexEncodedValue::Word(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}