sdml_core/model/constraints/formal/
functions.rs

1use crate::load::ModuleLoader;
2use crate::model::check::Validate;
3use crate::model::constraints::ConstraintSentence;
4use crate::model::identifiers::{Identifier, IdentifierReference};
5use crate::model::members::{CardinalityRange, MappingType, Ordering, Uniqueness};
6use crate::model::modules::Module;
7use crate::model::Span;
8use crate::store::ModuleStore;
9use crate::syntax::KW_WILDCARD;
10use std::fmt::Display;
11
12#[cfg(feature = "serde")]
13use serde::{Deserialize, Serialize};
14
15// ------------------------------------------------------------------------------------------------
16// Public Types ❱ Formal Constraints ❱ Environments ❱ Functions
17// ------------------------------------------------------------------------------------------------
18
19#[derive(Clone, Debug)]
20#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
21pub struct FunctionDef {
22    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
23    span: Option<Box<Span>>,
24    signature: FunctionSignature,
25    body: ConstraintSentence,
26}
27
28#[derive(Clone, Debug)]
29#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
30pub struct FunctionSignature {
31    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
32    span: Option<Box<Span>>,
33    parameters: Vec<FunctionParameter>,
34    target_type: FunctionType,
35}
36
37#[derive(Clone, Debug)]
38#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
39pub struct FunctionParameter {
40    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
41    span: Option<Box<Span>>,
42    name: Identifier,
43    target_type: FunctionType,
44}
45
46#[derive(Clone, Debug)]
47#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
48pub struct FunctionType {
49    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
50    span: Option<Box<Span>>,
51    target_cardinality: FunctionCardinality,
52    target_type: FunctionTypeReference,
53}
54
55/// Corresponds to the grammar rule `cardinality`.
56#[derive(Clone, Debug, Default, PartialEq, Eq)]
57#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
58pub struct FunctionCardinality {
59    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
60    span: Option<Box<Span>>,
61    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
62    ordering: Option<Ordering>,
63    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
64    uniqueness: Option<Uniqueness>,
65    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
66    range: Option<CardinalityRange>,
67}
68
69#[derive(Clone, Debug)]
70#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
71pub struct FunctionTypeReference {
72    optional: bool,
73    inner: FunctionTypeReferenceInner,
74}
75
76#[derive(Clone, Debug)]
77#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
78pub enum FunctionTypeReferenceInner {
79    Wildcard,
80    Reference(IdentifierReference),
81    // builtin_simple_type is converted into a reference
82    MappingType(MappingType),
83}
84
85// ------------------------------------------------------------------------------------------------
86// Implementations ❱ Formal Constraints ❱ Environments ❱ Functions
87// ------------------------------------------------------------------------------------------------
88
89impl_has_body_for!(FunctionDef, ConstraintSentence);
90
91impl_has_source_span_for!(FunctionDef);
92
93impl FunctionDef {
94    // --------------------------------------------------------------------------------------------
95    // Constructors
96    // --------------------------------------------------------------------------------------------
97
98    pub const fn new(signature: FunctionSignature, body: ConstraintSentence) -> Self {
99        Self {
100            span: None,
101            signature,
102            body,
103        }
104    }
105
106    // --------------------------------------------------------------------------------------------
107    // Fields
108    // --------------------------------------------------------------------------------------------
109
110    get_and_set!(pub signature, set_signature => FunctionSignature);
111}
112
113// ------------------------------------------------------------------------------------------------
114
115impl_has_source_span_for!(FunctionSignature);
116
117impl FunctionSignature {
118    // --------------------------------------------------------------------------------------------
119    // Constructors
120    // --------------------------------------------------------------------------------------------
121
122    pub fn new(parameters: Vec<FunctionParameter>, target_type: FunctionType) -> Self {
123        Self {
124            span: Default::default(),
125            parameters,
126            target_type,
127        }
128    }
129
130    // --------------------------------------------------------------------------------------------
131    // Fields
132    // --------------------------------------------------------------------------------------------
133
134    get_and_set_vec!(
135        pub
136        has has_parameters,
137        parameters_len,
138        parameters,
139        parameters_mut,
140        add_to_parameters,
141        extend_parameters
142            => parameters, FunctionParameter
143    );
144
145    get_and_set!(pub target_type, set_target_type => FunctionType);
146}
147
148// ------------------------------------------------------------------------------------------------
149
150impl_has_name_for!(FunctionParameter);
151
152impl_has_source_span_for!(FunctionParameter);
153
154impl FunctionParameter {
155    // --------------------------------------------------------------------------------------------
156    // Constructors
157    // --------------------------------------------------------------------------------------------
158
159    pub const fn new(name: Identifier, target_type: FunctionType) -> Self {
160        Self {
161            span: None,
162            name,
163            target_type,
164        }
165    }
166
167    // --------------------------------------------------------------------------------------------
168    // Fields
169    // --------------------------------------------------------------------------------------------
170
171    get_and_set!(pub target_type, set_target_type => FunctionType);
172}
173
174// ------------------------------------------------------------------------------------------------
175
176impl_has_source_span_for!(FunctionType);
177
178impl FunctionType {
179    // --------------------------------------------------------------------------------------------
180    // Constructors
181    // --------------------------------------------------------------------------------------------
182
183    pub fn new(
184        target_cardinality: FunctionCardinality,
185        target_type: FunctionTypeReference,
186    ) -> Self {
187        Self {
188            span: Default::default(),
189            target_cardinality,
190            target_type,
191        }
192    }
193
194    // --------------------------------------------------------------------------------------------
195    // Fields
196    // --------------------------------------------------------------------------------------------
197
198    pub fn with_wildcard_cardinality(self) -> Self {
199        Self {
200            target_cardinality: FunctionCardinality::new_wildcard(),
201            ..self
202        }
203    }
204
205    pub fn with_target_cardinality(self, target_cardinality: FunctionCardinality) -> Self {
206        Self {
207            target_cardinality,
208            ..self
209        }
210    }
211
212    get_and_set!(pub target_cardinality, set_target_cardinality => FunctionCardinality);
213
214    pub fn with_target_type(self, target_type: FunctionTypeReference) -> Self {
215        Self {
216            target_type,
217            ..self
218        }
219    }
220
221    get_and_set!(pub target_type, set_target_type => FunctionTypeReference);
222}
223
224// ------------------------------------------------------------------------------------------------
225
226impl Display for FunctionCardinality {
227    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
228        write!(
229            f,
230            "{{{}{}{}}}",
231            self.ordering.map(|c| format!("{} ", c)).unwrap_or_default(),
232            self.uniqueness
233                .map(|c| format!("{} ", c))
234                .unwrap_or_default(),
235            if let Some(range) = &self.range {
236                range.to_string()
237            } else {
238                KW_WILDCARD.to_string()
239            }
240        )
241    }
242}
243
244impl_has_source_span_for!(FunctionCardinality);
245
246impl Validate for FunctionCardinality {
247    fn validate(
248        &self,
249        _top: &Module,
250        _cache: &impl ModuleStore,
251        _loader: &impl ModuleLoader,
252        _check_constraints: bool,
253    ) {
254        todo!()
255    }
256}
257
258impl FunctionCardinality {
259    // --------------------------------------------------------------------------------------------
260    // Constructors
261    // --------------------------------------------------------------------------------------------
262
263    pub const fn new(
264        ordering: Option<Ordering>,
265        uniqueness: Option<Uniqueness>,
266        range: Option<CardinalityRange>,
267    ) -> Self {
268        Self {
269            span: None,
270            ordering,
271            uniqueness,
272            range,
273        }
274    }
275
276    pub const fn new_range(min: u32, max: u32) -> Self {
277        Self {
278            span: None,
279            ordering: None,
280            uniqueness: None,
281            range: Some(CardinalityRange::new_range(min, max)),
282        }
283    }
284
285    pub const fn new_unbounded(min: u32) -> Self {
286        Self {
287            span: None,
288            ordering: None,
289            uniqueness: None,
290            range: Some(CardinalityRange::new_unbounded(min)),
291        }
292    }
293
294    pub const fn new_single(min_and_max: u32) -> Self {
295        Self {
296            span: None,
297            ordering: None,
298            uniqueness: None,
299            range: Some(CardinalityRange::new_single(min_and_max)),
300        }
301    }
302
303    pub const fn new_wildcard() -> Self {
304        Self {
305            span: None,
306            ordering: None,
307            uniqueness: None,
308            range: None,
309        }
310    }
311
312    #[inline(always)]
313    pub const fn one() -> Self {
314        Self::new_single(1)
315    }
316
317    #[inline(always)]
318    pub const fn zero_or_one() -> Self {
319        Self::new_range(0, 1)
320    }
321
322    #[inline(always)]
323    pub const fn one_or_more() -> Self {
324        Self::new_unbounded(1)
325    }
326
327    #[inline(always)]
328    pub const fn zero_or_more() -> Self {
329        Self::new_unbounded(0)
330    }
331
332    // --------------------------------------------------------------------------------------------
333    // Fields
334    // --------------------------------------------------------------------------------------------
335
336    pub fn with_ordering(self, ordering: Ordering) -> Self {
337        Self {
338            ordering: Some(ordering),
339            ..self
340        }
341    }
342
343    get_and_set!(pub ordering, set_ordering, unset_ordering => optional copy has_ordering, Ordering);
344
345    #[inline(always)]
346    pub fn is_ordered(&self) -> Option<bool> {
347        self.ordering().map(|o| o == Ordering::Ordered)
348    }
349
350    // --------------------------------------------------------------------------------------------
351
352    #[inline(always)]
353    pub fn with_uniqueness(self, uniqueness: Uniqueness) -> Self {
354        Self {
355            uniqueness: Some(uniqueness),
356            ..self
357        }
358    }
359
360    get_and_set!(pub uniqueness, set_uniqueness, unset_uniqueness => optional copy has_uniqueness, Uniqueness);
361
362    #[inline(always)]
363    pub fn is_unique(&self) -> Option<bool> {
364        self.uniqueness().map(|u| u == Uniqueness::Unique)
365    }
366
367    // --------------------------------------------------------------------------------------------
368
369    get_and_set!(pub range, set_range, unset_range => optional has_range, CardinalityRange);
370
371    pub fn is_wildcard(&self) -> bool {
372        self.range.is_none()
373    }
374}
375
376// ------------------------------------------------------------------------------------------------
377
378impl From<FunctionTypeReferenceInner> for FunctionTypeReference {
379    fn from(inner: FunctionTypeReferenceInner) -> Self {
380        Self {
381            optional: false,
382            inner,
383        }
384    }
385}
386
387impl AsRef<FunctionTypeReferenceInner> for FunctionTypeReference {
388    fn as_ref(&self) -> &FunctionTypeReferenceInner {
389        &self.inner
390    }
391}
392
393impl FunctionTypeReference {
394    // --------------------------------------------------------------------------------------------
395    // Constructors
396    // --------------------------------------------------------------------------------------------
397
398    pub fn optional(inner: FunctionTypeReferenceInner) -> Self {
399        Self {
400            optional: true,
401            inner,
402        }
403    }
404
405    // --------------------------------------------------------------------------------------------
406    // Fields
407    // --------------------------------------------------------------------------------------------
408
409    pub fn is_optional(&self) -> bool {
410        self.optional
411    }
412
413    pub fn inner(&self) -> &FunctionTypeReferenceInner {
414        &self.inner
415    }
416}
417
418// ------------------------------------------------------------------------------------------------
419
420impl From<IdentifierReference> for FunctionTypeReferenceInner {
421    fn from(value: IdentifierReference) -> Self {
422        Self::Reference(value)
423    }
424}
425
426impl From<MappingType> for FunctionTypeReferenceInner {
427    fn from(value: MappingType) -> Self {
428        Self::MappingType(value)
429    }
430}
431
432impl FunctionTypeReferenceInner {
433    // --------------------------------------------------------------------------------------------
434    // Variants
435    // --------------------------------------------------------------------------------------------
436
437    is_as_variant!(Reference (IdentifierReference) => is_type_reference, as_type_reference);
438
439    is_as_variant!(MappingType (MappingType) => is_mapping_type, as_mapping_type);
440
441    is_variant!(Wildcard => is_wildcard);
442}