zerodds_idl_parse/dialect.rs
1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2026 ZeroDDS Contributors
3//! Which dialect the parser accepts. Spec §3.5.
4//!
5//! Strict OMG IDL 4.2 by default. A vendor flag admits that vendor's
6//! extensions, and a construct admitted only by a flag records which
7//! one — so a later validation against `Profile::Idl42Core` can say
8//! that the file is not portable and why.
9
10/// The set of dialects a parse accepts.
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
12pub struct Dialect {
13 /// RTI Connext extensions: `keylist`.
14 pub rti: bool,
15 /// Cyclone DDS extensions.
16 pub cyclone: bool,
17 /// eProsima Fast DDS extensions.
18 pub fast_dds: bool,
19 /// OpenDDS extensions.
20 pub open_dds: bool,
21 /// ROS 2 dialect: admits unqualified member types that differ only in case
22 /// from the member name (e.g., `Pose pose;`).
23 pub ros2: bool,
24}
25
26impl Dialect {
27 /// OMG IDL 4.2 and nothing else.
28 ///
29 /// The default, because a file that parses under it is one every
30 /// other vendor's compiler also reads.
31 pub const STRICT: Self = Self {
32 rti: false,
33 cyclone: false,
34 fast_dds: false,
35 open_dds: false,
36 ros2: false,
37 };
38
39 /// Every vendor dialect at once.
40 pub const ALL_VENDORS: Self = Self {
41 rti: true,
42 cyclone: true,
43 fast_dds: true,
44 open_dds: true,
45 ros2: false,
46 };
47
48 /// Whether any vendor extension is admitted.
49 #[must_use]
50 pub const fn any_vendor(self) -> bool {
51 self.rti || self.cyclone || self.fast_dds || self.open_dds || self.ros2
52 }
53
54 /// The name of the flag that admits a construct, for a diagnostic
55 /// that has to say what made a file unportable.
56 #[must_use]
57 pub const fn flag_name(admitted_by: VendorFlag) -> &'static str {
58 match admitted_by {
59 VendorFlag::Rti => "rti",
60 VendorFlag::Cyclone => "cyclone",
61 VendorFlag::FastDds => "fast_dds",
62 VendorFlag::OpenDds => "open_dds",
63 VendorFlag::Ros2 => "ros2",
64 }
65 }
66
67 /// Whether this dialect admits `flag`.
68 #[must_use]
69 pub const fn admits(self, flag: VendorFlag) -> bool {
70 match flag {
71 VendorFlag::Rti => self.rti,
72 VendorFlag::Cyclone => self.cyclone,
73 VendorFlag::FastDds => self.fast_dds,
74 VendorFlag::OpenDds => self.open_dds,
75 VendorFlag::Ros2 => self.ros2,
76 }
77 }
78}
79
80/// One vendor flag, for naming which admitted a construct.
81#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
82pub enum VendorFlag {
83 /// RTI Connext.
84 Rti,
85 /// Cyclone DDS.
86 Cyclone,
87 /// Fast DDS.
88 FastDds,
89 /// OpenDDS.
90 OpenDds,
91 /// ROS 2 dialect.
92 Ros2,
93}
94
95impl VendorFlag {
96 /// Every flag, so a test can assert the set is complete.
97 pub const ALL: [Self; 5] = [
98 Self::Rti,
99 Self::Cyclone,
100 Self::FastDds,
101 Self::OpenDds,
102 Self::Ros2,
103 ];
104}