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