sdml_core/model/mod.rs
1/*!
2Provide the Rust types that implement an in-memory representation of the SDML Grammar.
3*/
4
5use crate::model::identifiers::{Identifier, IdentifierReference};
6use std::{
7 collections::BTreeSet,
8 fmt::{Debug, Display},
9 hash::Hash,
10 ops::Range,
11};
12
13#[cfg(feature = "serde")]
14use serde::{Deserialize, Serialize};
15
16// ------------------------------------------------------------------------------------------------
17// Public Types ❱ Traits
18// ------------------------------------------------------------------------------------------------
19
20///
21/// This trait is implemented by types that have a distinct *body* type.
22///
23pub trait HasBody {
24 ///
25 /// This type is the particular body for the enclosing type.
26 ///
27 type Body;
28
29 ///
30 /// Get the body of the enclosing type.
31 ///
32 fn body(&self) -> &Self::Body;
33
34 ///
35 /// Get a mutable reference to the body of the enclosing type.
36 ///
37 fn body_mut(&mut self) -> &mut Self::Body;
38
39 ///
40 /// Set the body of the enclosing type.
41 ///
42 fn set_body(&mut self, body: Self::Body);
43}
44
45///
46/// This trait is implemented by types that have a unique name.
47///
48pub trait HasName {
49 ///
50 /// Get the name of the enclosing type.
51 ///
52 fn name(&self) -> &Identifier;
53
54 ///
55 /// Set the name of the enclosing type.
56 ///
57 fn set_name(&mut self, name: Identifier);
58}
59
60///
61/// This trait is implemented by types whose name is derived from a reference.
62///
63pub trait HasNameReference {
64 ///
65 /// Get the name reference for the enclosing type.
66 ///
67 fn name_reference(&self) -> &IdentifierReference;
68
69 ///
70 /// Set the name reference for the enclosing type.
71 ///
72 fn set_name_reference(&mut self, name: IdentifierReference);
73}
74
75///
76/// This trait is implemented by types that have a distinct, but optional, *body* type.
77///
78pub trait HasOptionalBody {
79 ///
80 /// This type is the particular body for the enclosing type.
81 ///
82 type Body;
83
84 fn has_body(&self) -> bool {
85 self.body().is_some()
86 }
87 fn body(&self) -> Option<&Self::Body>;
88 fn body_mut(&mut self) -> Option<&mut Self::Body>;
89 fn set_body(&mut self, body: Self::Body);
90 fn unset_body(&mut self);
91}
92
93///
94/// This trait is implemented by types that include a source location from which they were parsed.
95///
96pub trait HasSourceSpan {
97 fn with_source_span(self, ts_span: Span) -> Self;
98 fn has_source_span(&self) -> bool {
99 self.source_span().is_some()
100 }
101 fn source_span(&self) -> Option<&Span>;
102 fn set_source_span(&mut self, span: Span);
103 fn unset_source_span(&mut self);
104}
105
106///
107/// This trait is implemented by types to allow for query of references.
108///
109pub trait References {
110 #[allow(unused_variables)]
111 fn referenced_types<'a>(&'a self, names: &mut BTreeSet<&'a IdentifierReference>) {}
112
113 #[allow(unused_variables)]
114 fn referenced_annotations<'a>(&'a self, names: &mut BTreeSet<&'a IdentifierReference>) {}
115}
116
117// ------------------------------------------------------------------------------------------------
118// Public Types ❱ Structures
119// ------------------------------------------------------------------------------------------------
120
121///
122/// The source location information from the tree-sitter `Node` type. The location is stored as
123/// a start and end position, where the positions are byte indices.
124///
125#[derive(Clone, PartialEq, Eq, Hash)]
126#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
127pub struct Span(Range<usize>);
128
129// ------------------------------------------------------------------------------------------------
130// Implementations
131// ------------------------------------------------------------------------------------------------
132
133#[cfg(feature = "tree-sitter")]
134impl From<&tree_sitter::Node<'_>> for Span {
135 fn from(node: &tree_sitter::Node<'_>) -> Self {
136 Self(node.byte_range())
137 }
138}
139
140#[cfg(feature = "tree-sitter")]
141impl From<tree_sitter::Node<'_>> for Span {
142 fn from(node: tree_sitter::Node<'_>) -> Self {
143 Self::from(&node)
144 }
145}
146
147impl From<Span> for sdml_errors::Span {
148 fn from(value: Span) -> Self {
149 value.byte_range()
150 }
151}
152
153impl From<&Span> for sdml_errors::Span {
154 fn from(value: &Span) -> Self {
155 sdml_errors::Span::from(value.clone())
156 }
157}
158
159impl Debug for Span {
160 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
161 f.debug_struct("Span")
162 .field("start", &self.0.start)
163 .field("end", &self.0.end)
164 .finish()
165 }
166}
167
168impl Display for Span {
169 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
170 write!(f, "{}..{}", self.0.start, self.0.end)
171 }
172}
173
174impl Span {
175 // --------------------------------------------------------------------------------------------
176 // Constructors
177 // --------------------------------------------------------------------------------------------
178
179 /// Create a new span from the `start` byte and `end` byte indices.
180 #[inline(always)]
181 pub fn new(start: usize, end: usize) -> Self {
182 assert!(start <= end);
183 Self(start..end)
184 }
185
186 // --------------------------------------------------------------------------------------------
187 // Fields
188 // --------------------------------------------------------------------------------------------
189
190 /// Return the starting byte index of this span.
191 #[inline(always)]
192 pub fn start(&self) -> usize {
193 self.0.start
194 }
195
196 /// Return the ending byte index of this span.
197 #[inline(always)]
198 pub fn end(&self) -> usize {
199 self.0.end
200 }
201
202 /// Return this span as a `start..end` range.
203 #[inline(always)]
204 pub fn byte_range(&self) -> Range<usize> {
205 self.0.clone()
206 }
207}
208
209// ------------------------------------------------------------------------------------------------
210// Modules
211// ------------------------------------------------------------------------------------------------
212
213pub mod comments;
214
215pub mod annotations;
216
217pub mod check;
218
219pub mod constraints;
220
221pub mod definitions;
222
223pub mod identifiers;
224
225pub mod members;
226
227pub mod modules;
228
229pub mod values;
230
231pub mod walk;