Skip to main content

zerodds_ast/node/
mod.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2026 ZeroDDS Contributors
3//! The node space. Spec §3.
4
5pub mod annotation;
6pub mod constant;
7pub mod deployment;
8pub mod exception;
9pub mod interface;
10pub mod member;
11pub mod module;
12pub mod type_;
13
14pub use annotation::{AnnotationDefNode, AnnotationMemberNode};
15pub use constant::{
16    BinaryOp, ConstExpr, ConstExprNode, ConstNode, ConstValue, EvalError, Literal, UnaryOp,
17};
18pub use deployment::{
19    DomainNode, EndpointNode, EndpointRole, LibraryNode, ParticipantNode, QosPolicy, QosPolicyKind,
20    QosProfileNode, TopicNode,
21};
22pub use exception::ExceptionNode;
23pub use interface::{
24    AttributeNode, InterfaceKind, InterfaceNode, OperationNode, ParamDirection, ParamNode,
25};
26pub use member::{BitValueNode, BitfieldNode, CaseLabel, CaseNode, EnumeratorNode, MemberNode};
27pub use module::ModuleNode;
28pub use type_::{Bound, CharWidth, Completeness, PrimitiveKind, TypeKind, TypeNode, ValuetypeKind};
29
30use crate::kind::NodeKind;
31use zerodds_ast_core::{Id, NodeId};
32
33/// A handle to any node, carrying its kind and its stable identity.
34///
35/// Used where a container holds mixed kinds — a module's children, a
36/// member's parent — without erasing which kind each entry is.
37#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
38#[non_exhaustive]
39pub enum AnyId {
40    /// A module.
41    Module(Id<ModuleNode>, NodeId),
42    /// A type.
43    Type(Id<TypeNode>, NodeId),
44    /// An aggregate member.
45    Member(Id<MemberNode>, NodeId),
46    /// A union case.
47    Case(Id<CaseNode>, NodeId),
48    /// An enumerator.
49    Enumerator(Id<EnumeratorNode>, NodeId),
50    /// A bitmask bit.
51    BitValue(Id<BitValueNode>, NodeId),
52    /// A bitset field.
53    Bitfield(Id<BitfieldNode>, NodeId),
54    /// A constant.
55    Const(Id<ConstNode>, NodeId),
56    /// An expression node.
57    ConstExpr(Id<ConstExprNode>, NodeId),
58    /// An interface.
59    Interface(Id<InterfaceNode>, NodeId),
60    /// An operation.
61    Operation(Id<OperationNode>, NodeId),
62    /// An operation parameter.
63    Param(Id<ParamNode>, NodeId),
64    /// An interface attribute.
65    Attribute(Id<AttributeNode>, NodeId),
66    /// An exception.
67    Exception(Id<ExceptionNode>, NodeId),
68    /// An annotation declaration.
69    AnnotationDef(Id<AnnotationDefNode>, NodeId),
70    /// An annotation member.
71    AnnotationMember(Id<AnnotationMemberNode>, NodeId),
72    /// A domain.
73    Domain(Id<DomainNode>, NodeId),
74    /// A topic.
75    Topic(Id<TopicNode>, NodeId),
76    /// A QoS profile.
77    QosProfile(Id<QosProfileNode>, NodeId),
78    /// A participant.
79    Participant(Id<ParticipantNode>, NodeId),
80    /// An endpoint.
81    Endpoint(Id<EndpointNode>, NodeId),
82    /// A deployment library.
83    Library(Id<LibraryNode>, NodeId),
84}
85
86impl AnyId {
87    /// The node's stable identity.
88    #[must_use]
89    pub const fn node_id(self) -> NodeId {
90        match self {
91            Self::Module(_, id)
92            | Self::Type(_, id)
93            | Self::Member(_, id)
94            | Self::Case(_, id)
95            | Self::Enumerator(_, id)
96            | Self::BitValue(_, id)
97            | Self::Bitfield(_, id)
98            | Self::Const(_, id)
99            | Self::ConstExpr(_, id)
100            | Self::Interface(_, id)
101            | Self::Operation(_, id)
102            | Self::Param(_, id)
103            | Self::Attribute(_, id)
104            | Self::Exception(_, id)
105            | Self::AnnotationDef(_, id)
106            | Self::AnnotationMember(_, id)
107            | Self::Domain(_, id)
108            | Self::Topic(_, id)
109            | Self::QosProfile(_, id)
110            | Self::Participant(_, id)
111            | Self::Endpoint(_, id)
112            | Self::Library(_, id) => id,
113        }
114    }
115
116    /// The node's kind.
117    #[must_use]
118    pub const fn kind(self) -> NodeKind {
119        match self {
120            Self::Module(..) => NodeKind::Module,
121            Self::Type(..) => NodeKind::Type,
122            Self::Member(..) => NodeKind::Member,
123            Self::Case(..) => NodeKind::Case,
124            Self::Enumerator(..) => NodeKind::Enumerator,
125            Self::BitValue(..) => NodeKind::BitValue,
126            Self::Bitfield(..) => NodeKind::Bitfield,
127            Self::Const(..) => NodeKind::Const,
128            Self::ConstExpr(..) => NodeKind::ConstExpr,
129            Self::Interface(..) => NodeKind::Interface,
130            Self::Operation(..) => NodeKind::Operation,
131            Self::Param(..) => NodeKind::Param,
132            Self::Attribute(..) => NodeKind::Attribute,
133            Self::Exception(..) => NodeKind::Exception,
134            Self::AnnotationDef(..) => NodeKind::AnnotationDef,
135            Self::AnnotationMember(..) => NodeKind::AnnotationMember,
136            Self::Domain(..) => NodeKind::Domain,
137            Self::Topic(..) => NodeKind::Topic,
138            Self::QosProfile(..) => NodeKind::QosProfile,
139            Self::Participant(..) => NodeKind::Participant,
140            Self::Endpoint(..) => NodeKind::Endpoint,
141            Self::Library(..) => NodeKind::Library,
142        }
143    }
144
145    /// The type handle, if this names a type.
146    #[must_use]
147    pub const fn as_type(self) -> Option<Id<TypeNode>> {
148        match self {
149            Self::Type(id, _) => Some(id),
150            _ => None,
151        }
152    }
153
154    /// The interface handle, if this names an interface.
155    #[must_use]
156    pub const fn as_interface(self) -> Option<Id<crate::InterfaceNode>> {
157        match self {
158            Self::Interface(id, _) => Some(id),
159            _ => None,
160        }
161    }
162
163    /// The module handle, if this names a module.
164    #[must_use]
165    pub const fn as_module(self) -> Option<Id<ModuleNode>> {
166        match self {
167            Self::Module(id, _) => Some(id),
168            _ => None,
169        }
170    }
171
172    /// The member handle, if this names a member.
173    #[must_use]
174    pub const fn as_member(self) -> Option<Id<MemberNode>> {
175        match self {
176            Self::Member(id, _) => Some(id),
177            _ => None,
178        }
179    }
180}