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::{HasBody, HasName, HasSourceSpan, 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 ❱ Constraints ❱ 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<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<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<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<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<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 enum FunctionTypeReference {
72    Wildcard,
73    Reference(IdentifierReference),
74    // builtin_simple_type is converted into a reference
75    MappingType(MappingType),
76}
77
78// ------------------------------------------------------------------------------------------------
79// Implementations ❱ Constraints ❱ FunctionDef
80// ------------------------------------------------------------------------------------------------
81
82impl HasBody for FunctionDef {
83    type Body = ConstraintSentence;
84
85    fn body(&self) -> &Self::Body {
86        &self.body
87    }
88
89    fn body_mut(&mut self) -> &mut Self::Body {
90        &mut self.body
91    }
92
93    fn set_body(&mut self, body: Self::Body) {
94        self.body = body;
95    }
96}
97
98impl HasSourceSpan for FunctionDef {
99    fn with_source_span(self, span: Span) -> Self {
100        let mut self_mut = self;
101        self_mut.span = Some(span);
102        self_mut
103    }
104
105    fn source_span(&self) -> Option<&Span> {
106        self.span.as_ref()
107    }
108
109    fn set_source_span(&mut self, span: Span) {
110        self.span = Some(span);
111    }
112
113    fn unset_source_span(&mut self) {
114        self.span = None;
115    }
116}
117
118impl FunctionDef {
119    // --------------------------------------------------------------------------------------------
120    // Constructors
121    // --------------------------------------------------------------------------------------------
122
123    pub const fn new(signature: FunctionSignature, body: ConstraintSentence) -> Self {
124        Self {
125            span: None,
126            signature,
127            body,
128        }
129    }
130
131    // --------------------------------------------------------------------------------------------
132    // Fields
133    // --------------------------------------------------------------------------------------------
134
135    pub const fn signature(&self) -> &FunctionSignature {
136        &self.signature
137    }
138
139    pub fn set_signature(&mut self, signature: FunctionSignature) {
140        self.signature = signature;
141    }
142}
143
144// ------------------------------------------------------------------------------------------------
145// Implementations ❱ Constraints ❱ FunctionSignature
146// ------------------------------------------------------------------------------------------------
147
148impl HasSourceSpan for FunctionSignature {
149    fn with_source_span(self, span: Span) -> Self {
150        let mut self_mut = self;
151        self_mut.span = Some(span);
152        self_mut
153    }
154
155    fn source_span(&self) -> Option<&Span> {
156        self.span.as_ref()
157    }
158
159    fn set_source_span(&mut self, span: Span) {
160        self.span = Some(span);
161    }
162
163    fn unset_source_span(&mut self) {
164        self.span = None;
165    }
166}
167
168impl FunctionSignature {
169    // --------------------------------------------------------------------------------------------
170    // Constructors
171    // --------------------------------------------------------------------------------------------
172
173    pub fn new(parameters: Vec<FunctionParameter>, target_type: FunctionType) -> Self {
174        Self {
175            span: Default::default(),
176            parameters,
177            target_type,
178        }
179    }
180
181    // --------------------------------------------------------------------------------------------
182    // Fields
183    // --------------------------------------------------------------------------------------------
184
185    pub fn has_parameters(&self) -> bool {
186        !self.parameters.is_empty()
187    }
188
189    pub fn parameters_len(&self) -> usize {
190        self.parameters.len()
191    }
192
193    pub fn parameters(&self) -> impl Iterator<Item = &FunctionParameter> {
194        self.parameters.iter()
195    }
196
197    pub fn parameters_mut(&mut self) -> impl Iterator<Item = &mut FunctionParameter> {
198        self.parameters.iter_mut()
199    }
200
201    pub fn add_to_parameters<I>(&mut self, value: I)
202    where
203        I: Into<FunctionParameter>,
204    {
205        self.parameters.push(value.into())
206    }
207
208    pub fn extend_parameters<I>(&mut self, extension: I)
209    where
210        I: IntoIterator<Item = FunctionParameter>,
211    {
212        self.parameters.extend(extension)
213    }
214
215    // --------------------------------------------------------------------------------------------
216
217    pub const fn target_type(&self) -> &FunctionType {
218        &self.target_type
219    }
220
221    pub fn set_target_type(&mut self, target_type: FunctionType) {
222        self.target_type = target_type;
223    }
224}
225
226// ------------------------------------------------------------------------------------------------
227// Implementations ❱ Constraints ❱ FunctionParameter
228// ------------------------------------------------------------------------------------------------
229
230impl HasName for FunctionParameter {
231    fn name(&self) -> &Identifier {
232        &self.name
233    }
234
235    fn set_name(&mut self, name: Identifier) {
236        self.name = name;
237    }
238}
239
240impl HasSourceSpan for FunctionParameter {
241    fn with_source_span(self, span: Span) -> Self {
242        let mut self_mut = self;
243        self_mut.span = Some(span);
244        self_mut
245    }
246
247    fn source_span(&self) -> Option<&Span> {
248        self.span.as_ref()
249    }
250
251    fn set_source_span(&mut self, span: Span) {
252        self.span = Some(span);
253    }
254
255    fn unset_source_span(&mut self) {
256        self.span = None;
257    }
258}
259
260impl FunctionParameter {
261    // --------------------------------------------------------------------------------------------
262    // Constructors
263    // --------------------------------------------------------------------------------------------
264
265    pub const fn new(name: Identifier, target_type: FunctionType) -> Self {
266        Self {
267            span: None,
268            name,
269            target_type,
270        }
271    }
272
273    // --------------------------------------------------------------------------------------------
274    // Fields
275    // --------------------------------------------------------------------------------------------
276
277    pub const fn target_type(&self) -> &FunctionType {
278        &self.target_type
279    }
280
281    pub fn set_target_type(&mut self, target_type: FunctionType) {
282        self.target_type = target_type;
283    }
284}
285
286// ------------------------------------------------------------------------------------------------
287// Implementations ❱ Constraints ❱ FunctionType
288// ------------------------------------------------------------------------------------------------
289
290impl HasSourceSpan for FunctionType {
291    fn with_source_span(self, span: Span) -> Self {
292        let mut self_mut = self;
293        self_mut.span = Some(span);
294        self_mut
295    }
296
297    fn source_span(&self) -> Option<&Span> {
298        self.span.as_ref()
299    }
300
301    fn set_source_span(&mut self, span: Span) {
302        self.span = Some(span);
303    }
304
305    fn unset_source_span(&mut self) {
306        self.span = None;
307    }
308}
309
310impl FunctionType {
311    // --------------------------------------------------------------------------------------------
312    // Constructors
313    // --------------------------------------------------------------------------------------------
314
315    pub fn new(
316        target_cardinality: FunctionCardinality,
317        target_type: FunctionTypeReference,
318    ) -> Self {
319        Self {
320            span: Default::default(),
321            target_cardinality,
322            target_type,
323        }
324    }
325
326    pub fn with_wildcard_cardinality(self) -> Self {
327        let mut self_mut = self;
328        self_mut.target_cardinality = FunctionCardinality::new_wildcard();
329        self_mut
330    }
331
332    pub fn with_target_cardinality(self, target_cardinality: FunctionCardinality) -> Self {
333        let mut self_mut = self;
334        self_mut.target_cardinality = target_cardinality;
335        self_mut
336    }
337
338    pub fn with_target_type(self, target_type: FunctionTypeReference) -> Self {
339        let mut self_mut = self;
340        self_mut.target_type = target_type;
341        self_mut
342    }
343
344    // --------------------------------------------------------------------------------------------
345    // Fields
346    // --------------------------------------------------------------------------------------------
347
348    pub const fn target_cardinality(&self) -> &FunctionCardinality {
349        &self.target_cardinality
350    }
351
352    pub fn set_target_cardinality(&mut self, target_cardinality: FunctionCardinality) {
353        self.target_cardinality = target_cardinality;
354    }
355
356    // --------------------------------------------------------------------------------------------
357
358    pub const fn target_type(&self) -> &FunctionTypeReference {
359        &self.target_type
360    }
361
362    pub fn set_target_type(&mut self, target_type: FunctionTypeReference) {
363        self.target_type = target_type;
364    }
365}
366
367// ------------------------------------------------------------------------------------------------
368// Implementations ❱ Constraints ❱ FunctionCardinality
369// ------------------------------------------------------------------------------------------------
370
371impl Display for FunctionCardinality {
372    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
373        write!(
374            f,
375            "{{{}{}{}}}",
376            self.ordering.map(|c| format!("{} ", c)).unwrap_or_default(),
377            self.uniqueness
378                .map(|c| format!("{} ", c))
379                .unwrap_or_default(),
380            if let Some(range) = &self.range {
381                range.to_string()
382            } else {
383                KW_WILDCARD.to_string()
384            }
385        )
386    }
387}
388
389impl HasSourceSpan for FunctionCardinality {
390    fn with_source_span(self, span: Span) -> Self {
391        let mut self_mut = self;
392        self_mut.span = Some(span);
393        self_mut
394    }
395
396    fn source_span(&self) -> Option<&Span> {
397        self.span.as_ref()
398    }
399
400    fn set_source_span(&mut self, span: Span) {
401        self.span = Some(span);
402    }
403
404    fn unset_source_span(&mut self) {
405        self.span = None;
406    }
407}
408
409impl Validate for FunctionCardinality {
410    fn validate(
411        &self,
412        _top: &Module,
413        _cache: &impl ModuleStore,
414        _loader: &impl ModuleLoader,
415        _check_constraints: bool,
416    ) {
417        todo!()
418    }
419}
420
421impl FunctionCardinality {
422    // --------------------------------------------------------------------------------------------
423    // Constructors
424    // --------------------------------------------------------------------------------------------
425
426    pub const fn new(
427        ordering: Option<Ordering>,
428        uniqueness: Option<Uniqueness>,
429        range: Option<CardinalityRange>,
430    ) -> Self {
431        Self {
432            span: None,
433            ordering,
434            uniqueness,
435            range,
436        }
437    }
438
439    pub const fn new_range(min: u32, max: u32) -> Self {
440        Self {
441            span: None,
442            ordering: None,
443            uniqueness: None,
444            range: Some(CardinalityRange::new_range(min, max)),
445        }
446    }
447
448    pub const fn new_unbounded(min: u32) -> Self {
449        Self {
450            span: None,
451            ordering: None,
452            uniqueness: None,
453            range: Some(CardinalityRange::new_unbounded(min)),
454        }
455    }
456
457    pub const fn new_single(min_and_max: u32) -> Self {
458        Self {
459            span: None,
460            ordering: None,
461            uniqueness: None,
462            range: Some(CardinalityRange::new_single(min_and_max)),
463        }
464    }
465
466    pub const fn new_wildcard() -> Self {
467        Self {
468            span: None,
469            ordering: None,
470            uniqueness: None,
471            range: None,
472        }
473    }
474
475    #[inline(always)]
476    pub const fn one() -> Self {
477        Self::new_single(1)
478    }
479
480    #[inline(always)]
481    pub const fn zero_or_one() -> Self {
482        Self::new_range(0, 1)
483    }
484
485    #[inline(always)]
486    pub const fn one_or_more() -> Self {
487        Self::new_unbounded(1)
488    }
489
490    #[inline(always)]
491    pub const fn zero_or_more() -> Self {
492        Self::new_unbounded(0)
493    }
494
495    pub const fn with_uniqueness(self, uniqueness: Uniqueness) -> Self {
496        let mut self_mut = self;
497        self_mut.uniqueness = Some(uniqueness);
498        self_mut
499    }
500
501    pub const fn with_ordering(self, ordering: Ordering) -> Self {
502        let mut self_mut = self;
503        self_mut.ordering = Some(ordering);
504        self_mut
505    }
506
507    // --------------------------------------------------------------------------------------------
508    // Fields
509    // --------------------------------------------------------------------------------------------
510
511    pub const fn has_ordering(&self) -> bool {
512        self.ordering.is_some()
513    }
514
515    pub const fn ordering(&self) -> Option<Ordering> {
516        self.ordering
517    }
518
519    pub fn set_ordering(&mut self, ordering: Ordering) {
520        self.ordering = Some(ordering);
521    }
522
523    pub fn unset_ordering(&mut self) {
524        self.ordering = None;
525    }
526
527    #[inline(always)]
528    pub fn is_ordered(&self) -> Option<bool> {
529        self.ordering().map(|o| o == Ordering::Ordered)
530    }
531
532    // --------------------------------------------------------------------------------------------
533
534    pub const fn has_uniqueness(&self) -> bool {
535        self.uniqueness.is_some()
536    }
537
538    pub const fn uniqueness(&self) -> Option<Uniqueness> {
539        self.uniqueness
540    }
541
542    pub fn set_uniqueness(&mut self, uniqueness: Uniqueness) {
543        self.uniqueness = Some(uniqueness);
544    }
545
546    pub fn unset_uniqueness(&mut self) {
547        self.uniqueness = None;
548    }
549
550    #[inline(always)]
551    pub fn is_unique(&self) -> Option<bool> {
552        self.uniqueness().map(|u| u == Uniqueness::Unique)
553    }
554
555    // --------------------------------------------------------------------------------------------
556
557    pub const fn has_range(&self) -> bool {
558        self.range.is_some()
559    }
560
561    pub const fn range(&self) -> Option<&CardinalityRange> {
562        self.range.as_ref()
563    }
564
565    pub fn set_range(&mut self, range: CardinalityRange) {
566        self.range = Some(range);
567    }
568
569    pub fn unset_range(&mut self) {
570        self.range = None;
571    }
572
573    // --------------------------------------------------------------------------------------------
574
575    #[inline(always)]
576    pub fn is_default(&self) -> bool {
577        self.ordering.is_none()
578            && self.uniqueness.is_none()
579            && self.range.is_none()
580    }
581
582    pub fn is_wildcard(&self) -> bool {
583        self.range.is_none()
584    }
585}
586
587// ------------------------------------------------------------------------------------------------
588// Implementations ❱ Constraints ❱ FunctionTypeReference
589// ------------------------------------------------------------------------------------------------
590
591impl From<&IdentifierReference> for FunctionTypeReference {
592    fn from(value: &IdentifierReference) -> Self {
593        Self::Reference(value.clone())
594    }
595}
596
597impl From<IdentifierReference> for FunctionTypeReference {
598    fn from(value: IdentifierReference) -> Self {
599        Self::Reference(value)
600    }
601}
602
603impl From<&MappingType> for FunctionTypeReference {
604    fn from(value: &MappingType) -> Self {
605        Self::MappingType(value.clone())
606    }
607}
608
609impl From<MappingType> for FunctionTypeReference {
610    fn from(value: MappingType) -> Self {
611        Self::MappingType(value)
612    }
613}
614
615impl FunctionTypeReference {
616    // --------------------------------------------------------------------------------------------
617    // Variants
618    // --------------------------------------------------------------------------------------------
619
620    pub const fn is_reference(&self) -> bool {
621        matches!(self, Self::Reference(_))
622    }
623
624    pub const fn as_reference(&self) -> Option<&IdentifierReference> {
625        match self {
626            Self::Reference(v) => Some(v),
627            _ => None,
628        }
629    }
630
631    // --------------------------------------------------------------------------------------------
632
633    pub const fn is_mapping_type(&self) -> bool {
634        matches!(self, Self::MappingType(_))
635    }
636
637    pub const fn as_mapping_type(&self) -> Option<&MappingType> {
638        match self {
639            Self::MappingType(v) => Some(v),
640            _ => None,
641        }
642    }
643
644    // --------------------------------------------------------------------------------------------
645
646    pub const fn is_wildcard(&self) -> bool {
647        matches!(self, Self::Wildcard)
648    }
649}