xidl_parser/hir/
serialization.rs1use super::{Annotation, AnnotationParams};
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Serialize, Deserialize, Clone, Copy)]
5pub enum SerializeKind {
6 Cdr,
7 PlainCdr,
8 PlCdr,
9 PlainCdr2,
10 DelimitedCdr,
11 PlCdr2,
12}
13
14#[derive(Debug, Serialize, Deserialize, Clone, Copy)]
15pub enum SerializeVersion {
16 Xcdr1,
17 Xcdr2,
18}
19
20#[derive(Debug, Default, Serialize, Deserialize, Clone, Copy)]
21pub struct SerializeConfig {
22 pub explicit_kind: Option<SerializeKind>,
23 pub version: Option<SerializeVersion>,
24}
25
26#[derive(Debug, Serialize, Deserialize, Clone, Copy)]
27pub enum Extensibility {
28 Final,
29 Appendable,
30 Mutable,
31 None,
32}
33
34impl SerializeConfig {
35 pub fn apply_pragma(&mut self, pragma: super::Pragma) {
36 match pragma {
37 super::Pragma::Custom(_) => {}
38 super::Pragma::XidlcSerialize(kind) => self.explicit_kind = Some(kind),
39 super::Pragma::XidlcVersion(version) => {
40 self.version = Some(version);
41 self.explicit_kind = None;
42 }
43 super::Pragma::XidlcPackage(_)
44 | super::Pragma::XidlcOpenApiVersion(_)
45 | super::Pragma::XidlcOpenApiService { .. } => {}
46 }
47 }
48
49 pub fn resolve(&self, extensibility: Extensibility) -> SerializeKind {
50 if let Some(kind) = self.explicit_kind {
51 return kind;
52 }
53
54 match self.version {
55 None => SerializeKind::Cdr,
56 Some(SerializeVersion::Xcdr1) => match extensibility {
57 Extensibility::Mutable => SerializeKind::PlCdr,
58 Extensibility::Final | Extensibility::Appendable => SerializeKind::Cdr,
59 Extensibility::None => SerializeKind::PlainCdr,
60 },
61 Some(SerializeVersion::Xcdr2) => match extensibility {
62 Extensibility::Final => SerializeKind::PlainCdr2,
63 Extensibility::Appendable => SerializeKind::DelimitedCdr,
64 Extensibility::Mutable => SerializeKind::PlCdr2,
65 Extensibility::None => SerializeKind::Cdr,
66 },
67 }
68 }
69
70 pub fn resolve_for_annotations(&self, annotations: &[Annotation]) -> SerializeKind {
71 self.resolve(extensibility_from_annotations(annotations))
72 }
73}
74
75pub fn extensibility_from_annotations(annotations: &[Annotation]) -> Extensibility {
76 let mut final_flag = false;
77 let mut appendable = false;
78 let mut mutable = false;
79
80 for annotation in annotations {
81 if let Annotation::Builtin { name, .. } = annotation {
82 if name.eq_ignore_ascii_case("final") {
83 final_flag = true;
84 } else if name.eq_ignore_ascii_case("appendable") {
85 appendable = true;
86 } else if name.eq_ignore_ascii_case("mutable") {
87 mutable = true;
88 }
89 }
90
91 if let Annotation::Builtin { name, params } = annotation {
92 if name.eq_ignore_ascii_case("extensibility") {
93 if let Some(AnnotationParams::Raw(raw)) = params {
94 let value = raw.trim().trim_matches('"');
95 if value.eq_ignore_ascii_case("final") {
96 final_flag = true;
97 } else if value.eq_ignore_ascii_case("appendable") {
98 appendable = true;
99 } else if value.eq_ignore_ascii_case("mutable") {
100 mutable = true;
101 }
102 }
103 }
104 }
105 }
106
107 if mutable {
108 Extensibility::Mutable
109 } else if appendable {
110 Extensibility::Appendable
111 } else if final_flag {
112 Extensibility::Final
113 } else {
114 Extensibility::None
115 }
116}
117
118#[cfg(test)]
119mod tests;