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;