1mod enum_dcl;
2pub use enum_dcl::*;
3
4mod struct_dcl;
5pub use struct_dcl::*;
6
7mod annotation;
8pub use annotation::*;
9
10mod expr;
11pub use expr::*;
12
13mod declarator;
14pub use declarator::*;
15
16mod types;
17pub use types::*;
18
19mod const_dcl;
20pub use const_dcl::*;
21
22mod interface;
23pub use interface::*;
24
25mod type_dcl;
26pub use type_dcl::*;
27
28mod exception_dcl;
29pub use exception_dcl::*;
30
31mod interface_codegen;
32
33use serde::{Deserialize, Serialize};
34use serde_json::Value;
35use std::collections::HashMap;
36
37#[derive(Debug, Serialize, Deserialize, Clone)]
38pub struct Specification(pub Vec<Definition>);
39
40pub type ParserProperties = HashMap<String, Value>;
41
42#[derive(Debug, Serialize, Deserialize, Clone)]
43pub enum Definition {
44 ModuleDcl(ModuleDcl),
45 Pragma(Pragma),
46 ConstrTypeDcl(ConstrTypeDcl),
47 TypeDcl(TypeDcl),
48 ConstDcl(ConstDcl),
49 ExceptDcl(ExceptDcl),
50 InterfaceDcl(InterfaceDcl),
51}
52
53#[derive(Debug, Serialize, Deserialize, Clone)]
54pub struct ModuleDcl {
55 pub annotations: Vec<Annotation>,
56 pub ident: String,
57 pub definition: Vec<Definition>,
58}
59
60#[derive(Debug, Serialize, Deserialize, Clone, Copy)]
61pub enum SerializeKind {
62 Cdr,
63 PlainCdr,
64 PlCdr,
65 PlainCdr2,
66 DelimitedCdr,
67 PlCdr2,
68}
69
70#[derive(Debug, Serialize, Deserialize, Clone, Copy)]
71pub enum SerializeVersion {
72 Xcdr1,
73 Xcdr2,
74}
75
76#[derive(Debug, Default, Serialize, Deserialize, Clone, Copy)]
77pub struct SerializeConfig {
78 pub explicit_kind: Option<SerializeKind>,
79 pub version: Option<SerializeVersion>,
80}
81
82#[derive(Debug, Serialize, Deserialize, Clone)]
83pub enum Pragma {
84 XidlcSerialize(SerializeKind),
85 XidlcVersion(SerializeVersion),
86 XidlcPackage(String),
87 XidlcOpenApiVersion(String),
88 XidlcOpenApiService {
89 base_url: String,
90 description: Option<String>,
91 },
92}
93
94#[derive(Debug, Serialize, Deserialize, Clone, Copy)]
95pub enum Extensibility {
96 Final,
97 Appendable,
98 Mutable,
99 None,
100}
101
102impl SerializeConfig {
103 pub fn apply_pragma(&mut self, pragma: Pragma) {
104 match pragma {
105 Pragma::XidlcSerialize(kind) => {
106 self.explicit_kind = Some(kind);
107 }
108 Pragma::XidlcVersion(version) => {
109 self.version = Some(version);
110 self.explicit_kind = None;
111 }
112 Pragma::XidlcPackage(_)
113 | Pragma::XidlcOpenApiVersion(_)
114 | Pragma::XidlcOpenApiService { .. } => {}
115 }
116 }
117
118 pub fn resolve(&self, extensibility: Extensibility) -> SerializeKind {
119 if let Some(kind) = self.explicit_kind {
120 return kind;
121 }
122
123 match self.version {
124 None => SerializeKind::Cdr,
125 Some(SerializeVersion::Xcdr1) => match extensibility {
126 Extensibility::Mutable => SerializeKind::PlCdr,
127 Extensibility::Final | Extensibility::Appendable => SerializeKind::Cdr,
128 Extensibility::None => SerializeKind::PlainCdr,
129 },
130 Some(SerializeVersion::Xcdr2) => match extensibility {
131 Extensibility::Final => SerializeKind::PlainCdr2,
132 Extensibility::Appendable => SerializeKind::DelimitedCdr,
133 Extensibility::Mutable => SerializeKind::PlCdr2,
134 Extensibility::None => SerializeKind::Cdr,
135 },
136 }
137 }
138
139 pub fn resolve_for_annotations(&self, annotations: &[Annotation]) -> SerializeKind {
140 self.resolve(extensibility_from_annotations(annotations))
141 }
142}
143
144pub fn extensibility_from_annotations(annotations: &[Annotation]) -> Extensibility {
145 let mut final_flag = false;
146 let mut appendable = false;
147 let mut mutable = false;
148 for anno in annotations {
149 if let Annotation::Builtin { name, .. } = anno {
150 if name.eq_ignore_ascii_case("final") {
151 final_flag = true;
152 } else if name.eq_ignore_ascii_case("appendable") {
153 appendable = true;
154 } else if name.eq_ignore_ascii_case("mutable") {
155 mutable = true;
156 }
157 }
158 if let Annotation::Builtin { name, params } = anno {
159 if name.eq_ignore_ascii_case("extensibility") {
160 if let Some(AnnotationParams::Raw(raw)) = params {
161 let value = raw.trim().trim_matches('"');
162 if value.eq_ignore_ascii_case("final") {
163 final_flag = true;
164 } else if value.eq_ignore_ascii_case("appendable") {
165 appendable = true;
166 } else if value.eq_ignore_ascii_case("mutable") {
167 mutable = true;
168 }
169 }
170 }
171 }
172 }
173
174 if mutable {
175 Extensibility::Mutable
176 } else if appendable {
177 Extensibility::Appendable
178 } else if final_flag {
179 Extensibility::Final
180 } else {
181 Extensibility::None
182 }
183}
184
185#[derive(Debug, Serialize, Deserialize, Clone)]
186pub enum ConstrTypeDcl {
187 StructForwardDcl(StructForwardDcl),
188 StructDcl(StructDcl),
189 EnumDcl(EnumDcl),
190 UnionForwardDcl(UnionForwardDcl),
191 UnionDef(UnionDef),
192 BitsetDcl(BitsetDcl),
193 BitmaskDcl(BitmaskDcl),
194}
195
196#[derive(Debug, Serialize, Deserialize, Clone)]
197pub struct UnionForwardDcl {
198 pub annotations: Vec<Annotation>,
199 pub ident: String,
200}
201
202#[derive(Debug, Serialize, Deserialize, Clone)]
203pub struct UnionDef {
204 pub annotations: Vec<Annotation>,
205 pub ident: String,
206 pub switch_type_spec: SwitchTypeSpec,
207 pub case: Vec<Case>,
208}
209
210impl UnionDef {
211 pub fn serialize_kind(&self, config: &SerializeConfig) -> SerializeKind {
212 config.resolve_for_annotations(&self.annotations)
213 }
214}
215
216#[derive(Debug, Serialize, Deserialize, Clone)]
217pub struct Case {
218 pub label: Vec<CaseLabel>,
219 pub element: ElementSpec,
220}
221
222#[derive(Debug, Serialize, Deserialize, Clone)]
223pub enum CaseLabel {
224 Value(ConstExpr),
225 Default,
226}
227
228#[derive(Debug, Serialize, Deserialize, Clone)]
229pub struct ElementSpec {
230 pub annotations: Vec<Annotation>,
231 pub ty: ElementSpecTy,
232 pub value: Declarator,
233 pub field_id: Option<u32>,
234}
235
236#[derive(Debug, Serialize, Deserialize, Clone)]
237pub enum ElementSpecTy {
238 TypeSpec(TypeSpec),
239 ConstrTypeDcl(ConstrTypeDcl),
240}
241
242#[derive(Debug, Serialize, Deserialize, Clone)]
243pub enum SwitchTypeSpec {
244 IntegerType(IntegerType),
245 CharType,
246 WideCharType,
247 BooleanType,
248 ScopedName(ScopedName),
249 OctetType,
250}
251
252#[derive(Debug, Serialize, Deserialize, Clone)]
253pub struct BitsetDcl {
254 pub annotations: Vec<Annotation>,
255 pub ident: String,
256 pub parent: Option<ScopedName>,
257 pub field: Vec<BitField>,
258}
259
260impl BitsetDcl {
261 pub fn serialize_kind(&self, config: &SerializeConfig) -> SerializeKind {
262 config.resolve_for_annotations(&self.annotations)
263 }
264}
265
266#[derive(Clone, Debug, Serialize, Deserialize)]
267pub enum BitFieldType {
268 Bool,
269 Octec,
270 SignedInt,
271 UnsignedInt,
272}
273
274#[derive(Debug, Serialize, Deserialize, Clone)]
275pub struct BitField {
276 pub ident: String,
277 pub pos: PositiveIntConst,
278 pub ty: Option<BitFieldType>,
279}
280
281#[derive(Debug, Serialize, Deserialize, Clone)]
282pub struct BitmaskDcl {
283 pub annotations: Vec<Annotation>,
284 pub ident: String,
285 pub value: Vec<BitValue>,
286}
287
288impl BitmaskDcl {
289 pub fn serialize_kind(&self, config: &SerializeConfig) -> SerializeKind {
290 config.resolve_for_annotations(&self.annotations)
291 }
292}
293
294#[derive(Debug, Serialize, Deserialize, Clone)]
295pub struct BitValue {
296 pub annotations: Vec<Annotation>,
297 pub ident: String,
298}
299
300#[derive(Debug, Clone, Serialize, Deserialize)]
301pub struct ScopedName {
302 pub name: Vec<String>,
303 pub is_root: bool,
304}
305
306impl From<crate::typed_ast::ScopedName> for ScopedName {
307 fn from(typed_ast: crate::typed_ast::ScopedName) -> Self {
308 let is_root = typed_ast.node_text.starts_with("::");
309 let mut v = vec![];
310 get_scoped_name(&mut v, &typed_ast);
311 let name = v.into_iter().map(ToOwned::to_owned).collect();
312
313 Self { name, is_root }
314 }
315}
316
317fn get_scoped_name<'a>(pre: &mut Vec<&'a str>, value: &'a crate::typed_ast::ScopedName) {
318 if let Some(value) = &value.scoped_name {
319 get_scoped_name(pre, value);
320 }
321
322 pre.push(&value.identifier.0);
323}
324
325impl From<crate::typed_ast::Specification> for Specification {
326 fn from(value: crate::typed_ast::Specification) -> Self {
327 spec_from_typed_ast(value, true)
328 }
329}
330
331impl Specification {
332 pub fn from_typed_ast_with_properties(
333 value: crate::typed_ast::Specification,
334 properties: ParserProperties,
335 ) -> Self {
336 let expand_interface = properties
337 .get("expand_interface")
338 .and_then(Value::as_bool)
339 .unwrap_or(true);
340 spec_from_typed_ast(value, expand_interface)
341 }
342}
343
344pub(crate) fn spec_from_typed_ast(
345 value: crate::typed_ast::Specification,
346 expand_interfaces: bool,
347) -> Specification {
348 let mut defs = Vec::new();
349 let mut modules = Vec::new();
350 collect_defs(value.0, &mut modules, expand_interfaces, &mut defs);
351 Specification(defs)
352}
353
354fn collect_defs(
355 defs: Vec<crate::typed_ast::Definition>,
356 modules: &mut Vec<String>,
357 expand_interfaces: bool,
358 out: &mut Vec<Definition>,
359) {
360 for def in defs {
361 match def {
362 crate::typed_ast::Definition::ModuleDcl(module) => {
363 let ident = module.ident.0;
364 let annotations = expand_annotations(module.annotations);
365 modules.push(ident.clone());
366 let mut inner = Vec::new();
367 collect_defs(module.definition, modules, expand_interfaces, &mut inner);
368 modules.pop();
369 out.push(Definition::ModuleDcl(ModuleDcl {
370 annotations,
371 ident,
372 definition: inner,
373 }));
374 }
375 crate::typed_ast::Definition::PreprocCall(call) => {
376 if let Some(pragma) = parse_xidlc_pragma(&call) {
377 out.push(Definition::Pragma(pragma));
378 }
379 }
380 crate::typed_ast::Definition::TypeDcl(type_dcl) => {
381 let type_dcl: TypeDcl = type_dcl.into();
382 out.push(Definition::TypeDcl(type_dcl));
383 }
384 crate::typed_ast::Definition::ConstDcl(const_dcl) => {
385 out.push(Definition::ConstDcl(const_dcl.into()));
386 }
387 crate::typed_ast::Definition::ExceptDcl(except_dcl) => {
388 out.push(Definition::ExceptDcl(except_dcl.into()));
389 }
390 crate::typed_ast::Definition::InterfaceDcl(interface_dcl) => {
391 let interface: InterfaceDcl = interface_dcl.into();
392 if expand_interfaces {
393 let extra = interface_codegen::expand_interface(&interface, modules)
394 .unwrap_or_else(|err| {
395 panic!("interface expansion failed: {err}");
396 });
397 out.extend(extra);
398 }
399 out.push(Definition::InterfaceDcl(interface));
400 }
401 crate::typed_ast::Definition::TemplateModuleDcl(_)
402 | crate::typed_ast::Definition::TemplateModuleInst(_)
403 | crate::typed_ast::Definition::PreprocInclude(_)
404 | crate::typed_ast::Definition::PreprocDefine(_) => {}
405 }
406 }
407}
408
409fn parse_xidlc_pragma(call: &crate::typed_ast::PreprocCall) -> Option<Pragma> {
410 let directive = call.directive.0.as_str();
411 if !directive.eq_ignore_ascii_case("#pragma") && !directive.eq_ignore_ascii_case("#progma") {
412 return None;
413 }
414 let arg = call.argument.as_ref()?.0.as_str();
415 let mut parts = arg.split_whitespace();
416 let namespace = parts.next()?;
417 if !namespace.eq_ignore_ascii_case("xidlc") {
418 return None;
419 }
420 let token = parts.next()?;
421 let rest = parts.collect::<Vec<_>>().join(" ");
422
423 if token.eq_ignore_ascii_case("XCDR1") {
424 return Some(Pragma::XidlcVersion(SerializeVersion::Xcdr1));
425 }
426 if token.eq_ignore_ascii_case("XCDR2") {
427 return Some(Pragma::XidlcVersion(SerializeVersion::Xcdr2));
428 }
429 if token.eq_ignore_ascii_case("package") {
430 if !rest.is_empty() {
431 return Some(Pragma::XidlcPackage(trim_pragma_value(&rest)));
432 }
433 return None;
434 }
435 if token.eq_ignore_ascii_case("version") {
436 if !rest.is_empty() {
437 return Some(Pragma::XidlcOpenApiVersion(trim_pragma_value(&rest)));
438 }
439 return None;
440 }
441 if token.eq_ignore_ascii_case("service") {
442 if let Some((base_url, description)) = parse_pragma_service(&rest) {
443 return Some(Pragma::XidlcOpenApiService {
444 base_url,
445 description,
446 });
447 }
448 return None;
449 }
450
451 if let Some(inner) = token
452 .strip_prefix("serialize(")
453 .and_then(|value| value.strip_suffix(')'))
454 {
455 let inner = inner.trim();
456 if inner.eq_ignore_ascii_case("XCDR1") {
457 return Some(Pragma::XidlcVersion(SerializeVersion::Xcdr1));
458 }
459 if inner.eq_ignore_ascii_case("XCDR2") {
460 return Some(Pragma::XidlcVersion(SerializeVersion::Xcdr2));
461 }
462 if let Some(kind) = parse_serialize_kind(inner) {
463 return Some(Pragma::XidlcSerialize(kind));
464 }
465 }
466
467 None
468}
469
470fn trim_pragma_value(value: &str) -> String {
471 let value = value.trim();
472 if value.len() >= 2 {
473 let first = value.chars().next().unwrap();
474 let last = value.chars().last().unwrap();
475 if (first == '"' && last == '"') || (first == '\'' && last == '\'') {
476 return value[1..value.len() - 1].to_string();
477 }
478 }
479 value.to_string()
480}
481
482fn parse_pragma_service(value: &str) -> Option<(String, Option<String>)> {
483 let value = value.trim();
484 if value.is_empty() {
485 return None;
486 }
487
488 let mut base_url = None;
489 let mut remainder = "";
490
491 if value.starts_with('"') || value.starts_with('\'') {
492 let quote = value.chars().next().unwrap();
493 let mut end = None;
494 for (index, ch) in value.char_indices().skip(1) {
495 if ch == quote {
496 end = Some(index);
497 break;
498 }
499 }
500 if let Some(end) = end {
501 base_url = Some(value[1..end].to_string());
502 remainder = value[end + 1..].trim();
503 }
504 }
505
506 if base_url.is_none() {
507 let mut parts = value.splitn(2, char::is_whitespace);
508 base_url = parts.next().map(str::to_string);
509 remainder = parts.next().unwrap_or("").trim();
510 }
511
512 let base_url = base_url?;
513 let description = if remainder.is_empty() {
514 None
515 } else {
516 Some(trim_pragma_value(remainder))
517 };
518
519 Some((base_url, description))
520}
521
522fn parse_serialize_kind(value: &str) -> Option<SerializeKind> {
523 let value = value.trim();
524 if value.eq_ignore_ascii_case("CDR") {
525 Some(SerializeKind::Cdr)
526 } else if value.eq_ignore_ascii_case("PLAIN_CDR") {
527 Some(SerializeKind::PlainCdr)
528 } else if value.eq_ignore_ascii_case("PL_CDR") {
529 Some(SerializeKind::PlCdr)
530 } else if value.eq_ignore_ascii_case("PLAIN_CDR2") {
531 Some(SerializeKind::PlainCdr2)
532 } else if value.eq_ignore_ascii_case("DELIMITED_CDR") {
533 Some(SerializeKind::DelimitedCdr)
534 } else if value.eq_ignore_ascii_case("PL_CDR2") {
535 Some(SerializeKind::PlCdr2)
536 } else {
537 None
538 }
539}
540
541impl From<crate::typed_ast::ConstrTypeDcl> for ConstrTypeDcl {
542 fn from(value: crate::typed_ast::ConstrTypeDcl) -> Self {
543 match value {
544 crate::typed_ast::ConstrTypeDcl::StructDcl(struct_dcl) => struct_dcl.into(),
545 crate::typed_ast::ConstrTypeDcl::UnionDcl(union_dcl) => union_dcl.into(),
546 crate::typed_ast::ConstrTypeDcl::EnumDcl(enum_dcl) => Self::EnumDcl(enum_dcl.into()),
547 crate::typed_ast::ConstrTypeDcl::BitsetDcl(bitset_dcl) => {
548 Self::BitsetDcl(bitset_dcl.into())
549 }
550 crate::typed_ast::ConstrTypeDcl::BitmaskDcl(bitmask_dcl) => {
551 Self::BitmaskDcl(bitmask_dcl.into())
552 }
553 }
554 }
555}
556
557impl From<crate::typed_ast::StructDcl> for ConstrTypeDcl {
558 fn from(value: crate::typed_ast::StructDcl) -> Self {
559 match value {
560 crate::typed_ast::StructDcl::StructForwardDcl(forward) => {
561 Self::StructForwardDcl(forward.into())
562 }
563 crate::typed_ast::StructDcl::StructDef(def) => Self::StructDcl(def.into()),
564 }
565 }
566}
567
568impl From<crate::typed_ast::UnionDcl> for ConstrTypeDcl {
569 fn from(value: crate::typed_ast::UnionDcl) -> Self {
570 match value {
571 crate::typed_ast::UnionDcl::UnionForwardDcl(forward) => {
572 Self::UnionForwardDcl(forward.into())
573 }
574 crate::typed_ast::UnionDcl::UnionDef(def) => Self::UnionDef(def.into()),
575 }
576 }
577}
578
579impl From<crate::typed_ast::UnionForwardDcl> for UnionForwardDcl {
580 fn from(value: crate::typed_ast::UnionForwardDcl) -> Self {
581 Self {
582 annotations: vec![],
583 ident: value.0.0,
584 }
585 }
586}
587
588impl From<crate::typed_ast::UnionDef> for UnionDef {
589 fn from(value: crate::typed_ast::UnionDef) -> Self {
590 let mut cases = value
591 .case
592 .into_iter()
593 .map(Into::into)
594 .collect::<Vec<Case>>();
595 let mut member_ids = std::collections::HashMap::new();
596 let mut next_field_id = 1u32;
597 for case in cases.iter_mut() {
598 let name = declarator_name(&case.element.value).to_string();
599 if let Some(id) = case.element.field_id {
600 let entry = member_ids.entry(name.clone()).or_insert(id);
601 case.element.field_id = Some(*entry);
602 continue;
603 }
604 if let Some(existing) = member_ids.get(&name) {
605 case.element.field_id = Some(*existing);
606 continue;
607 }
608 member_ids.insert(name, next_field_id);
609 case.element.field_id = Some(next_field_id);
610 next_field_id += 1;
611 }
612 Self {
613 annotations: vec![],
614 ident: value.ident.0,
615 switch_type_spec: value.switch_type_spec.into(),
616 case: cases,
617 }
618 }
619}
620
621impl From<crate::typed_ast::Case> for Case {
622 fn from(value: crate::typed_ast::Case) -> Self {
623 Self {
624 label: value.label.into_iter().map(Into::into).collect(),
625 element: value.element.into(),
626 }
627 }
628}
629
630impl From<crate::typed_ast::CaseLabel> for CaseLabel {
631 fn from(value: crate::typed_ast::CaseLabel) -> Self {
632 match value {
633 crate::typed_ast::CaseLabel::Case(expr) => Self::Value(expr.into()),
634 crate::typed_ast::CaseLabel::Default => Self::Default,
635 }
636 }
637}
638
639impl From<crate::typed_ast::ElementSpec> for ElementSpec {
640 fn from(value: crate::typed_ast::ElementSpec) -> Self {
641 let annotations = expand_annotations(value.annotations);
642 let field_id = annotation_id_value(&annotations);
643 Self {
644 annotations,
645 ty: value.ty.into(),
646 value: value.value.into(),
647 field_id,
648 }
649 }
650}
651
652impl From<crate::typed_ast::ElementSpecTy> for ElementSpecTy {
653 fn from(value: crate::typed_ast::ElementSpecTy) -> Self {
654 match value {
655 crate::typed_ast::ElementSpecTy::TypeSpec(ty) => Self::TypeSpec(ty.into()),
656 crate::typed_ast::ElementSpecTy::ConstrTypeDcl(constr) => {
657 Self::ConstrTypeDcl(constr.into())
658 }
659 }
660 }
661}
662
663impl From<crate::typed_ast::SwitchTypeSpec> for SwitchTypeSpec {
664 fn from(value: crate::typed_ast::SwitchTypeSpec) -> Self {
665 match value {
666 crate::typed_ast::SwitchTypeSpec::IntegerType(integer_type) => {
667 Self::IntegerType(integer_type.into())
668 }
669 crate::typed_ast::SwitchTypeSpec::CharType(_) => Self::CharType,
670 crate::typed_ast::SwitchTypeSpec::WideCharType(_) => Self::WideCharType,
671 crate::typed_ast::SwitchTypeSpec::BooleanType(_) => Self::BooleanType,
672 crate::typed_ast::SwitchTypeSpec::ScopedName(scoped_name) => {
673 Self::ScopedName(scoped_name.into())
674 }
675 crate::typed_ast::SwitchTypeSpec::OctetType(_) => Self::OctetType,
676 }
677 }
678}
679
680fn declarator_name(value: &Declarator) -> &str {
681 match value {
682 Declarator::SimpleDeclarator(value) => &value.0,
683 Declarator::ArrayDeclarator(value) => &value.ident,
684 }
685}
686
687impl From<crate::typed_ast::BitsetDcl> for BitsetDcl {
688 fn from(value: crate::typed_ast::BitsetDcl) -> Self {
689 let mut field = Vec::new();
690 for bitfield in value.field {
691 let pos = bitfield.spec.pos;
692 let ty = bitfield.spec.dst_ty.map(Into::into);
693 for ident in bitfield.ident {
694 field.push(BitField {
695 ident: ident.0,
696 pos: pos.clone().into(),
697 ty: ty.clone(),
698 });
699 }
700 }
701
702 Self {
703 annotations: vec![],
704 ident: value.ident.0,
705 parent: value.parent.map(Into::into),
706 field,
707 }
708 }
709}
710
711impl From<crate::typed_ast::DestinationType> for BitFieldType {
712 fn from(value: crate::typed_ast::DestinationType) -> Self {
713 match value {
714 crate::typed_ast::DestinationType::BooleanType(_) => Self::Bool,
715 crate::typed_ast::DestinationType::OctetType(_) => Self::Octec,
716 crate::typed_ast::DestinationType::IntegerType(integer_type) => {
717 if matches!(integer_type, crate::typed_ast::IntegerType::SignedInt(_)) {
718 Self::SignedInt
719 } else {
720 Self::UnsignedInt
721 }
722 }
723 }
724 }
725}
726
727impl From<crate::typed_ast::BitmaskDcl> for BitmaskDcl {
728 fn from(value: crate::typed_ast::BitmaskDcl) -> Self {
729 Self {
730 annotations: vec![],
731 ident: value.ident.0,
732 value: value.value.into_iter().map(Into::into).collect(),
733 }
734 }
735}
736
737impl From<crate::typed_ast::BitValue> for BitValue {
738 fn from(value: crate::typed_ast::BitValue) -> Self {
739 Self {
740 annotations: expand_annotations(value.annotations),
741 ident: value.ident.0,
742 }
743 }
744}