sdml_core/model/constraints/formal/
terms.rs

1use crate::model::constraints::{PredicateValue, SequenceBuilder};
2use crate::model::identifiers::{Identifier, IdentifierReference, QualifiedIdentifier};
3use crate::model::{HasSourceSpan, Span};
4
5#[cfg(feature = "serde")]
6use serde::{Deserialize, Serialize};
7
8// ------------------------------------------------------------------------------------------------
9// Public Types ❱ Constraints ❱ Terms
10// ------------------------------------------------------------------------------------------------
11
12/// Corresponds to the grammar rule `term`.
13#[derive(Clone, Debug)]
14#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
15pub enum Term {
16    Sequence(Box<SequenceBuilder>),
17    Function(Box<FunctionalTerm>),
18    Composition(FunctionComposition),
19    Identifier(IdentifierReference),
20    ReservedSelf,
21    Value(PredicateValue),
22}
23
24///
25/// Corresponds to the grammar rule `function_composition`.
26///
27/// # Well-Formedness Rules
28///
29/// 1. The list of function names MUST have at least one element.
30///
31/// $$\forall r \in FunctionComposition \left( |name(r)| \gte 1 \right)$$
32///
33/// # Semantics
34///
35/// The keyword **`self`** may ONLY appear as the first element.
36///
37/// The name path $x.y.z$ is equivalent to $z(y(x))$, or $(z \circ y)(x)$.
38///
39/// For example:
40///
41/// `self.name.length` becomes `length(name(self))`
42///
43#[derive(Clone, Debug)]
44#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
45pub struct FunctionComposition {
46    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
47    span: Option<Span>,
48    subject: Subject,                // assert!(!is_empty())
49    function_names: Vec<Identifier>, // ditto
50}
51
52/// Corresponds to the field `subject` in the grammar rule `name`.
53#[derive(Clone, Debug)]
54#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
55pub enum Subject {
56    /// Corresponds to the grammar rule `reserved_self`, or the keyword **`self`**.
57    ReservedSelf,
58    Identifier(Identifier),
59}
60
61/// Corresponds to the grammar rule `functional_term`.
62#[derive(Clone, Debug)]
63#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
64pub struct FunctionalTerm {
65    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
66    span: Option<Span>,
67    function: Term,
68    arguments: Vec<Term>,
69}
70
71// ------------------------------------------------------------------------------------------------
72// Implementations ❱ Constraints ❱ Term
73// ------------------------------------------------------------------------------------------------
74
75impl From<FunctionComposition> for Term {
76    fn from(v: FunctionComposition) -> Self {
77        Self::Composition(v)
78    }
79}
80
81impl From<IdentifierReference> for Term {
82    fn from(v: IdentifierReference) -> Self {
83        Self::Identifier(v)
84    }
85}
86
87impl From<Identifier> for Term {
88    fn from(v: Identifier) -> Self {
89        Self::Identifier(v.into())
90    }
91}
92
93impl From<QualifiedIdentifier> for Term {
94    fn from(v: QualifiedIdentifier) -> Self {
95        Self::Identifier(v.into())
96    }
97}
98
99impl From<PredicateValue> for Term {
100    fn from(v: PredicateValue) -> Self {
101        Self::Value(v)
102    }
103}
104
105impl From<FunctionalTerm> for Term {
106    fn from(v: FunctionalTerm) -> Self {
107        Self::Function(Box::new(v))
108    }
109}
110
111impl From<Box<FunctionalTerm>> for Term {
112    fn from(v: Box<FunctionalTerm>) -> Self {
113        Self::Function(v)
114    }
115}
116
117impl From<SequenceBuilder> for Term {
118    fn from(v: SequenceBuilder) -> Self {
119        Self::Sequence(Box::new(v))
120    }
121}
122
123impl From<Box<SequenceBuilder>> for Term {
124    fn from(v: Box<SequenceBuilder>) -> Self {
125        Self::Sequence(v)
126    }
127}
128
129impl Term {
130    // --------------------------------------------------------------------------------------------
131    // Variants
132    // --------------------------------------------------------------------------------------------
133
134    pub const fn is_sequence(&self) -> bool {
135        match self {
136            Self::Sequence(_) => true,
137            _ => false,
138        }
139    }
140    pub const fn as_sequence(&self) -> Option<&SequenceBuilder> {
141        match self {
142            Self::Sequence(v) => Some(v),
143            _ => None,
144        }
145    }
146
147    // --------------------------------------------------------------------------------------------
148
149    pub const fn is_function(&self) -> bool {
150        match self {
151            Self::Function(_) => true,
152            _ => false,
153        }
154    }
155
156    pub const fn as_function(&self) -> Option<&FunctionalTerm> {
157        match self {
158            Self::Function(v) => Some(v),
159            _ => None,
160        }
161    }
162
163    // --------------------------------------------------------------------------------------------
164
165    pub const fn is_call(&self) -> bool {
166        match self {
167            Self::Composition(_) => true,
168            _ => false,
169        }
170    }
171
172    pub const fn as_call(&self) -> Option<&FunctionComposition> {
173        match self {
174            Self::Composition(v) => Some(v),
175            _ => None,
176        }
177    }
178
179    // --------------------------------------------------------------------------------------------
180
181    pub const fn is_identifier(&self) -> bool {
182        match self {
183            Self::Identifier(_) => true,
184            _ => false,
185        }
186    }
187
188    pub const fn as_identifier(&self) -> Option<&IdentifierReference> {
189        match self {
190            Self::Identifier(v) => Some(v),
191            _ => None,
192        }
193    }
194
195    // --------------------------------------------------------------------------------------------
196
197    pub const fn is_value(&self) -> bool {
198        match self {
199            Self::Value(_) => true,
200            _ => false,
201        }
202    }
203
204    pub const fn as_value(&self) -> Option<&PredicateValue> {
205        match self {
206            Self::Value(v) => Some(v),
207            _ => None,
208        }
209    }
210}
211
212// ------------------------------------------------------------------------------------------------
213// Implementations ❱ Constraints ❱ FunctionComposition
214// ------------------------------------------------------------------------------------------------
215
216impl HasSourceSpan for FunctionComposition {
217    fn with_source_span(self, span: Span) -> Self {
218        let mut self_mut = self;
219        self_mut.span = Some(span);
220        self_mut
221    }
222
223    fn source_span(&self) -> Option<&Span> {
224        self.span.as_ref()
225    }
226
227    fn set_source_span(&mut self, span: Span) {
228        self.span = Some(span);
229    }
230
231    fn unset_source_span(&mut self) {
232        self.span = None;
233    }
234}
235
236impl FunctionComposition {
237    // --------------------------------------------------------------------------------------------
238    // Constructors
239    // --------------------------------------------------------------------------------------------
240
241    pub fn new<S, N>(subject: S, function_names: N) -> Self
242    where
243        S: Into<Subject>,
244        N: Into<Vec<Identifier>>,
245    {
246        let function_names = function_names.into();
247        assert!(!function_names.is_empty());
248        Self {
249            span: Default::default(),
250            subject: subject.into(),
251            function_names,
252        }
253    }
254
255    // --------------------------------------------------------------------------------------------
256    // Fields
257    // --------------------------------------------------------------------------------------------
258
259    pub fn subject(&self) -> &Subject {
260        &self.subject
261    }
262
263    pub fn set_subject<S>(&mut self, subject: S)
264    where
265        S: Into<Subject>,
266    {
267        self.subject = subject.into();
268    }
269
270    // --------------------------------------------------------------------------------------------
271
272    pub fn has_function_names(&self) -> bool {
273        !self.function_names.is_empty()
274    }
275
276    pub fn function_names_len(&self) -> usize {
277        self.function_names.len()
278    }
279
280    pub fn function_names(&self) -> impl Iterator<Item = &Identifier> {
281        self.function_names.iter()
282    }
283
284    pub fn function_names_mut(&mut self) -> impl Iterator<Item = &mut Identifier> {
285        self.function_names.iter_mut()
286    }
287
288    pub fn add_to_function_names<I>(&mut self, value: I)
289    where
290        I: Into<Identifier>,
291    {
292        self.function_names.push(value.into())
293    }
294
295    pub fn extend_function_names<I>(&mut self, extension: I)
296    where
297        I: IntoIterator<Item = Identifier>,
298    {
299        self.function_names.extend(extension)
300    }
301}
302
303// ------------------------------------------------------------------------------------------------
304// Implementations ❱ Constraints ❱ Subject
305// ------------------------------------------------------------------------------------------------
306
307impl From<&Identifier> for Subject {
308    fn from(v: &Identifier) -> Self {
309        Self::Identifier(v.clone())
310    }
311}
312
313impl From<Identifier> for Subject {
314    fn from(v: Identifier) -> Self {
315        Self::Identifier(v)
316    }
317}
318
319impl Subject {
320    // --------------------------------------------------------------------------------------------
321    // Variants
322    // --------------------------------------------------------------------------------------------
323
324    pub const fn is_reserved_self(&self) -> bool {
325        match self {
326            Self::ReservedSelf => true,
327            _ => false,
328        }
329    }
330
331    // --------------------------------------------------------------------------------------------
332
333    pub const fn is_identifier(&self) -> bool {
334        match self {
335            Self::Identifier(_) => true,
336            _ => false,
337        }
338    }
339
340    pub const fn as_identifier(&self) -> Option<&Identifier> {
341        match self {
342            Self::Identifier(v) => Some(v),
343            _ => None,
344        }
345    }
346}
347
348// ------------------------------------------------------------------------------------------------
349// Implementations ❱ Constraints ❱ FunctionalTerm
350// ------------------------------------------------------------------------------------------------
351
352impl HasSourceSpan for FunctionalTerm {
353    fn with_source_span(self, span: Span) -> Self {
354        let mut self_mut = self;
355        self_mut.span = Some(span);
356        self_mut
357    }
358
359    fn source_span(&self) -> Option<&Span> {
360        self.span.as_ref()
361    }
362
363    fn set_source_span(&mut self, span: Span) {
364        self.span = Some(span);
365    }
366
367    fn unset_source_span(&mut self) {
368        self.span = None;
369    }
370}
371
372impl FunctionalTerm {
373    // --------------------------------------------------------------------------------------------
374    // Constructors
375    // --------------------------------------------------------------------------------------------
376
377    pub fn new<T>(function: T) -> Self
378    where
379        T: Into<Term>,
380    {
381        Self {
382            span: Default::default(),
383            function: function.into(),
384            arguments: Default::default(),
385        }
386    }
387
388    pub fn new_with_arguments<T, A>(function: T, arguments: A) -> Self
389    where
390        T: Into<Term>,
391        A: Into<Vec<Term>>,
392    {
393        Self {
394            span: Default::default(),
395            function: function.into(),
396            arguments: arguments.into(),
397        }
398    }
399
400    // --------------------------------------------------------------------------------------------
401    // Fields
402    // --------------------------------------------------------------------------------------------
403
404    pub const fn function(&self) -> &Term {
405        &self.function
406    }
407
408    pub fn set_function(&mut self, function: Term) {
409        self.function = function;
410    }
411
412    // --------------------------------------------------------------------------------------------
413
414    pub fn has_arguments(&self) -> bool {
415        !self.arguments.is_empty()
416    }
417
418    pub fn arguments_len(&self) -> usize {
419        self.arguments.len()
420    }
421
422    pub fn arguments(&self) -> impl Iterator<Item = &Term> {
423        self.arguments.iter()
424    }
425
426    pub fn arguments_mut(&mut self) -> impl Iterator<Item = &mut Term> {
427        self.arguments.iter_mut()
428    }
429
430    pub fn add_to_arguments<I>(&mut self, value: I)
431    where
432        I: Into<Term>,
433    {
434        self.arguments.push(value.into())
435    }
436
437    pub fn extend_arguments<I>(&mut self, extension: I)
438    where
439        I: IntoIterator<Item = Term>,
440    {
441        self.arguments.extend(extension)
442    }
443}