xidl_parser/hir/
annotation.rs1use super::*;
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Serialize, Deserialize, Clone)]
5pub enum Annotation {
6 Id {
7 value: ConstExpr,
8 },
9 Key,
10 Builtin {
11 name: String,
12 params: Option<AnnotationParams>,
13 },
14 ScopedName {
15 name: ScopedName,
16 params: Option<AnnotationParams>,
17 },
18}
19
20#[derive(Debug, Serialize, Deserialize, Clone)]
21pub enum AnnotationParams {
22 ConstExpr(ConstExpr),
23 Params(Vec<AnnotationParam>),
24 Raw(String),
25}
26
27#[derive(Debug, Serialize, Deserialize, Clone)]
28pub struct AnnotationParam {
29 pub ident: String,
30 pub value: Option<ConstExpr>,
31}
32
33pub fn annotation_id_value(annotations: &[Annotation]) -> Option<u32> {
34 for annotation in annotations {
35 if let Annotation::Id { value } = annotation {
36 if let Some(value) = super::expr::const_expr_to_i64(value) {
37 if value >= 0 && value <= u32::MAX as i64 {
38 return Some(value as u32);
39 }
40 }
41 }
42 }
43 None
44}
45
46pub fn expand_annotations(values: Vec<crate::typed_ast::AnnotationAppl>) -> Vec<Annotation> {
47 let mut out = Vec::new();
48 for value in values {
49 push_annotation(&mut out, value);
50 }
51 out
52}
53
54fn push_annotation(out: &mut Vec<Annotation>, mut value: crate::typed_ast::AnnotationAppl) {
55 let extra = std::mem::take(&mut value.extra);
56 out.push(Annotation::from(value));
57 for item in extra {
58 push_annotation(out, item);
59 }
60}
61
62impl From<crate::typed_ast::AnnotationAppl> for Annotation {
63 fn from(value: crate::typed_ast::AnnotationAppl) -> Self {
64 let params = value.params.map(Into::into);
65 match value.name {
66 crate::typed_ast::AnnotationName::ScopedName(name) => Self::ScopedName {
67 name: name.into(),
68 params,
69 },
70 crate::typed_ast::AnnotationName::Builtin(name) => {
71 if name.eq_ignore_ascii_case("id") {
72 if let Some(AnnotationParams::ConstExpr(expr)) = ¶ms {
73 return Self::Id {
74 value: expr.clone(),
75 };
76 }
77 } else if name.eq_ignore_ascii_case("key") {
78 if params.is_none() {
79 return Self::Key;
80 }
81 }
82 Self::Builtin { name, params }
83 }
84 }
85 }
86}
87
88impl From<crate::typed_ast::AnnotationParams> for AnnotationParams {
89 fn from(value: crate::typed_ast::AnnotationParams) -> Self {
90 match value {
91 crate::typed_ast::AnnotationParams::ConstExpr(expr) => Self::ConstExpr(expr.into()),
92 crate::typed_ast::AnnotationParams::Params(params) => {
93 Self::Params(params.into_iter().map(Into::into).collect())
94 }
95 crate::typed_ast::AnnotationParams::Raw(value) => Self::Raw(value),
96 }
97 }
98}
99
100impl From<crate::typed_ast::AnnotationApplParam> for AnnotationParam {
101 fn from(value: crate::typed_ast::AnnotationApplParam) -> Self {
102 Self {
103 ident: value.ident.0,
104 value: value.value.map(Into::into),
105 }
106 }
107}