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::HashSet,
8    fmt::{Debug, Display},
9    hash::Hash,
10    ops::Range,
11};
12
13#[cfg(feature = "serde")]
14use serde::{Deserialize, Serialize};
15
16/// ------------------------------------------------------------------------------------------------
17/// Load the macros
18/// ------------------------------------------------------------------------------------------------
19#[macro_use]
20mod macros;
21
22// ------------------------------------------------------------------------------------------------
23// Public Types ❱ Traits
24// ------------------------------------------------------------------------------------------------
25
26///
27/// This trait is implemented by types that have a distinct *body* type.
28///
29pub trait HasBody {
30    ///
31    /// This type is the particular body for the enclosing type.
32    ///
33    type Body;
34
35    ///
36    /// Get the body of the enclosing type.
37    ///
38    fn body(&self) -> &Self::Body;
39
40    ///
41    /// Get a mutable reference to the body of the enclosing type.
42    ///
43    fn body_mut(&mut self) -> &mut Self::Body;
44
45    ///
46    /// Set the body of the enclosing type.
47    ///
48    fn set_body(&mut self, body: Self::Body);
49}
50
51///
52/// This trait is implemented by types that have a unique name.
53///
54pub trait HasName {
55    ///
56    /// Get the name of the enclosing type.
57    ///
58    fn name(&self) -> &Identifier;
59
60    ///
61    /// Set the name of the enclosing type.
62    ///
63    fn set_name(&mut self, name: Identifier);
64}
65
66///
67/// This trait is implemented by types whose name is derived from a reference.
68///
69pub trait HasNameReference {
70    ///
71    /// Get the name reference for the enclosing type.
72    ///
73    fn name_reference(&self) -> &IdentifierReference;
74
75    ///
76    /// Set the name reference for the enclosing type.
77    ///
78    fn set_name_reference(&mut self, name: IdentifierReference);
79}
80
81///
82/// This trait is implemented by types that have uniquely named members such as modules and
83/// structures.
84///
85pub trait Namespace {
86    type Member: HasName;
87
88    ///
89    /// Returns `true` of the namespace contains any members, else `false`.
90    ///
91    fn has_members(&self) -> bool;
92
93    ///
94    /// Returns the number of members in the namespace.
95    ///
96    fn member_count(&self) -> usize;
97
98    ///
99    /// Returns `true` if the namespace contains a member named `name`, else `false`.
100    ///
101    fn contains_member(&self, name: &Identifier) -> bool;
102
103    ///
104    /// Return the member with the name `name`, if present.
105    ///
106    fn member(&self, name: &Identifier) -> Option<&Self::Member>;
107
108    ///
109    /// Returns an iterator over all members in the namespace.
110    ///
111    fn members(&self) -> impl Iterator<Item = &Self::Member>;
112
113    ///
114    /// Returns an iterator over mutable members in the namespace.
115    ///
116    fn members_mut(&mut self) -> impl Iterator<Item = &mut Self::Member>;
117
118    ///
119    /// Returns an iterator over the names of namespace members.
120    ///
121    fn member_names(&self) -> impl Iterator<Item = &Identifier>;
122
123    ///
124    /// Add a member to the namespace. If a member already existed with the same name it
125    /// will be returned.
126    ///
127    fn add_to_members(&mut self, value: Self::Member) -> Option<Self::Member>;
128
129    ///
130    /// Add the members of the extension to the namespace. Any existing members with
131    /// the same names will be replaced.
132    ///
133    fn extend_members<I>(&mut self, extension: I)
134    where
135        I: IntoIterator<Item = Self::Member>;
136}
137
138///
139/// This trait is implemented by types that have a distinct, but optional, *body* type.
140///
141pub trait HasOptionalBody {
142    ///
143    /// This type is the particular body for the enclosing type.
144    ///
145    type Body;
146
147    fn has_body(&self) -> bool {
148        self.body().is_some()
149    }
150    fn body(&self) -> Option<&Self::Body>;
151    fn body_mut(&mut self) -> Option<&mut Self::Body>;
152    fn set_body(&mut self, body: Self::Body);
153    fn unset_body(&mut self);
154}
155
156///
157/// This trait is implemented by types that include a source location from which they were parsed.
158///
159pub trait HasSourceSpan {
160    fn with_source_span(self, ts_span: Span) -> Self;
161    fn has_source_span(&self) -> bool {
162        self.source_span().is_some()
163    }
164    fn source_span(&self) -> Option<&Span>;
165    fn set_source_span(&mut self, span: Span);
166    fn unset_source_span(&mut self);
167}
168
169///
170/// This trait is implemented by types to allow for query of references.
171///
172pub trait References {
173    #[allow(unused_variables)]
174    fn referenced_types<'a>(&'a self, names: &mut HashSet<&'a IdentifierReference>) {}
175
176    #[allow(unused_variables)]
177    fn referenced_annotations<'a>(&'a self, names: &mut HashSet<&'a IdentifierReference>) {}
178}
179
180// ------------------------------------------------------------------------------------------------
181// Public Types ❱ Structures
182// ------------------------------------------------------------------------------------------------
183
184///
185/// The source location information from the tree-sitter `Node` type. The location is stored as
186/// a start and end position, where the positions are byte indices.
187///
188#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
189#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
190pub struct Span {
191    start: SpanPosition,
192    end: SpanPosition,
193}
194
195#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
196#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
197pub struct SpanPosition {
198    byte: usize,
199    line: usize,
200    column: usize,
201}
202
203// ------------------------------------------------------------------------------------------------
204// Implementations
205// ------------------------------------------------------------------------------------------------
206
207#[cfg(feature = "tree-sitter")]
208impl From<&tree_sitter::Node<'_>> for Span {
209    fn from(node: &tree_sitter::Node<'_>) -> Self {
210        Self {
211            start: SpanPosition::from(node.start_position(), node.start_byte()),
212            end: SpanPosition::from(node.end_position(), node.end_byte()),
213        }
214    }
215}
216
217#[cfg(feature = "tree-sitter")]
218impl From<tree_sitter::Node<'_>> for Span {
219    fn from(node: tree_sitter::Node<'_>) -> Self {
220        Self::from(&node)
221    }
222}
223
224impl From<&Span> for sdml_errors::Span {
225    fn from(value: &Span) -> Self {
226        value.byte_range()
227    }
228}
229
230impl From<Span> for sdml_errors::Span {
231    fn from(value: Span) -> Self {
232        value.byte_range()
233    }
234}
235
236impl Display for Span {
237    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
238        write!(f, "{}..{}", self.start.byte, self.end.byte)
239    }
240}
241
242impl Span {
243    // --------------------------------------------------------------------------------------------
244    // Constructors
245    // --------------------------------------------------------------------------------------------
246
247    /// Create a new span from the `start` byte and `end` byte indices.
248    #[inline(always)]
249    pub fn new(start: SpanPosition, end: SpanPosition) -> Self {
250        assert!(start.byte <= end.byte);
251        assert!(start.line <= end.line);
252        assert!(start.column <= end.column || end.line > start.line);
253
254        Self { start, end }
255    }
256
257    // --------------------------------------------------------------------------------------------
258    // Fields
259    // --------------------------------------------------------------------------------------------
260
261    /// Return the starting byte index of this span.
262    #[inline(always)]
263    pub fn start(&self) -> SpanPosition {
264        self.start
265    }
266
267    /// Return the ending byte index of this span.
268    #[inline(always)]
269    pub fn end(&self) -> SpanPosition {
270        self.end
271    }
272
273    /// Return this span as a `start..end` range.
274    #[inline(always)]
275    pub fn byte_range(&self) -> Range<usize> {
276        self.start.byte..self.end.byte
277    }
278}
279
280impl SpanPosition {
281    // --------------------------------------------------------------------------------------------
282    // Constructors
283    // --------------------------------------------------------------------------------------------
284
285    /// Create a new span position from the `byte`, `line`, and `column` indices.
286    #[inline(always)]
287    pub fn new(byte: usize, line: usize, column: usize) -> Self {
288        Self { byte, line, column }
289    }
290
291    /// Create a new span position from the `byte` and tree-sitter point.
292    #[cfg(feature = "tree-sitter")]
293    pub fn from(node_point: tree_sitter::Point, byte: usize) -> Self {
294        Self::new(byte, node_point.row + 1, node_point.column + 1)
295    }
296
297    pub const fn byte(&self) -> usize {
298        self.byte
299    }
300
301    pub const fn line(&self) -> usize {
302        self.line
303    }
304
305    pub const fn column(&self) -> usize {
306        self.column
307    }
308}
309
310// ------------------------------------------------------------------------------------------------
311// Modules
312// ------------------------------------------------------------------------------------------------
313
314pub mod annotations;
315
316pub mod check;
317
318pub mod constraints;
319
320pub mod definitions;
321
322pub mod identifiers;
323
324pub mod members;
325
326pub mod modules;
327
328pub mod values;
329
330pub mod walk;