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 match annotation {
82 Annotation::Final => final_flag = true,
83 Annotation::Appendable => appendable = true,
84 Annotation::Mutable => mutable = true,
85 Annotation::Extensibility { kind } => {
86 if kind.eq_ignore_ascii_case("final") {
87 final_flag = true;
88 } else if kind.eq_ignore_ascii_case("appendable") {
89 appendable = true;
90 } else if kind.eq_ignore_ascii_case("mutable") {
91 mutable = true;
92 }
93 }
94 Annotation::Builtin {
95 name,
96 params: Some(AnnotationParams::Raw(raw)),
97 } if name.eq_ignore_ascii_case("extensibility") => {
98 let value = raw.trim().trim_matches('"');
99 if value.eq_ignore_ascii_case("final") {
100 final_flag = true;
101 } else if value.eq_ignore_ascii_case("appendable") {
102 appendable = true;
103 } else if value.eq_ignore_ascii_case("mutable") {
104 mutable = true;
105 }
106 }
107 _ => {}
108 }
109 }
110
111 if mutable {
112 Extensibility::Mutable
113 } else if appendable {
114 Extensibility::Appendable
115 } else if final_flag {
116 Extensibility::Final
117 } else {
118 Extensibility::None
119 }
120}
121
122#[cfg(test)]
123mod tests;