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