sdml_core/model/definitions/
classes.rs

1/*!
2One-line description.
3
4More detailed description, with
5
6# Example
7
8YYYYY
9
10*/
11
12use crate::load::ModuleLoader;
13use crate::model::annotations::{
14    Annotation, AnnotationBuilder, AnnotationProperty, HasAnnotations,
15};
16use crate::model::check::{MaybeIncomplete, Validate};
17use crate::model::constraints::{ConstraintSentence, FunctionCardinality, FunctionSignature};
18use crate::model::identifiers::{Identifier, IdentifierReference};
19use crate::model::modules::Module;
20use crate::model::values::Value;
21use crate::model::{HasName, HasOptionalBody, HasSourceSpan, References, Span};
22use crate::store::ModuleStore;
23use std::collections::{BTreeMap, BTreeSet};
24
25use sdml_errors::diagnostics::functions::IdentifierCaseConvention;
26#[cfg(feature = "serde")]
27use serde::{Deserialize, Serialize};
28
29// ------------------------------------------------------------------------------------------------
30// Public Types ❱ Definitions ❱ Type Classes
31// ------------------------------------------------------------------------------------------------
32
33/// Corresponds to the grammar rule `type_class_def`.
34#[derive(Clone, Debug)]
35#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
36pub struct TypeClassDef {
37    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
38    span: Option<Span>,
39    name: Identifier,
40    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Vec::is_empty"))]
41    variables: Vec<TypeVariable>, // assert 1..
42    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
43    body: Option<TypeClassBody>,
44}
45
46/// Corresponds to the grammar rule `type_variable`.
47#[derive(Clone, Debug)]
48#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
49pub struct TypeVariable {
50    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
51    span: Option<Span>,
52    name: Identifier,
53    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
54    cardinality: Option<FunctionCardinality>,
55    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Vec::is_empty"))]
56    restrictions: Vec<TypeClassReference>,
57}
58
59/// Corresponds to the grammar rule `type_class_reference`.
60#[derive(Clone, Debug)]
61#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
62pub struct TypeClassReference {
63    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
64    span: Option<Span>,
65    name: IdentifierReference,
66    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Vec::is_empty"))]
67    arguments: Vec<TypeClassArgument>, // 0..
68}
69
70/// Corresponds to the grammar rule `type_class_arguments`.
71#[derive(Clone, Debug)]
72#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
73pub enum TypeClassArgument {
74    Wildcard,
75    Reference(Box<TypeClassReference>),
76}
77
78/// Corresponds to the grammar rule `type_class_body`.
79#[derive(Clone, Debug, Default)]
80#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
81pub struct TypeClassBody {
82    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
83    span: Option<Span>,
84    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Vec::is_empty"))]
85    annotations: Vec<Annotation>,
86    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "BTreeMap::is_empty"))]
87    methods: BTreeMap<Identifier, MethodDef>,
88}
89
90/// Corresponds to the grammar rule `method_def`.
91#[derive(Clone, Debug)]
92#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
93pub struct MethodDef {
94    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
95    span: Option<Span>,
96    name: Identifier,
97    signature: FunctionSignature,
98    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
99    body: Option<ConstraintSentence>,
100    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Vec::is_empty"))]
101    annotations: Vec<Annotation>,
102}
103
104// ------------------------------------------------------------------------------------------------
105// Implementations ❱ Definitions ❱ TypeClassDef
106// ------------------------------------------------------------------------------------------------
107
108impl HasName for TypeClassDef {
109    fn name(&self) -> &Identifier {
110        &self.name
111    }
112
113    fn set_name(&mut self, name: Identifier) {
114        self.name = name;
115    }
116}
117
118impl HasOptionalBody for TypeClassDef {
119    type Body = TypeClassBody;
120
121    fn body(&self) -> Option<&Self::Body> {
122        self.body.as_ref()
123    }
124
125    fn body_mut(&mut self) -> Option<&mut Self::Body> {
126        self.body.as_mut()
127    }
128
129    fn set_body(&mut self, body: Self::Body) {
130        self.body = Some(body);
131    }
132
133    fn unset_body(&mut self) {
134        self.body = None;
135    }
136}
137
138impl HasSourceSpan for TypeClassDef {
139    fn with_source_span(self, span: Span) -> Self {
140        let mut self_mut = self;
141        self_mut.span = Some(span);
142        self_mut
143    }
144
145    fn source_span(&self) -> Option<&Span> {
146        self.span.as_ref()
147    }
148
149    fn set_source_span(&mut self, span: Span) {
150        self.span = Some(span);
151    }
152
153    fn unset_source_span(&mut self) {
154        self.span = None;
155    }
156}
157
158impl AnnotationBuilder for TypeClassDef {
159    fn with_predicate<I, V>(self, predicate: I, value: V) -> Self
160    where
161        Self: Sized,
162        I: Into<IdentifierReference>,
163        V: Into<Value>,
164    {
165        let mut self_mut = self;
166        if let Some(ref mut inner) = self_mut.body {
167            inner.add_to_annotations(AnnotationProperty::new(predicate.into(), value.into()));
168        }
169        self_mut
170    }
171}
172
173impl MaybeIncomplete for TypeClassDef {
174    fn is_incomplete(&self, _: &Module, _: &impl ModuleStore) -> bool {
175        self.body.is_none()
176    }
177}
178
179impl References for TypeClassDef {
180    fn referenced_types<'a>(&'a self, _names: &mut BTreeSet<&'a IdentifierReference>) {}
181
182    fn referenced_annotations<'a>(&'a self, _names: &mut BTreeSet<&'a IdentifierReference>) {}
183}
184
185impl Validate for TypeClassDef {
186    fn validate(
187        &self,
188        top: &crate::model::modules::Module,
189        _cache: &impl ModuleStore,
190        loader: &impl ModuleLoader,
191        _check_constraints: bool,
192    ) {
193        self.name()
194            .validate(top, loader, Some(IdentifierCaseConvention::TypeDefinition));
195        todo!()
196    }
197}
198
199impl TypeClassDef {
200    // --------------------------------------------------------------------------------------------
201    // Constructors
202    // --------------------------------------------------------------------------------------------
203
204    pub fn new<I>(name: Identifier, variables: I) -> Self
205    where
206        I: IntoIterator<Item = TypeVariable>,
207    {
208        Self {
209            span: None,
210            name,
211            variables: Vec::from_iter(variables),
212            body: None,
213        }
214    }
215
216    // --------------------------------------------------------------------------------------------
217    // Fields
218    // --------------------------------------------------------------------------------------------
219
220    pub fn has_variables(&self) -> bool {
221        !self.variables.is_empty()
222    }
223
224    pub fn variable_count(&self) -> usize {
225        self.variables.len()
226    }
227
228    pub fn variables(&self) -> impl Iterator<Item = &TypeVariable> {
229        self.variables.iter()
230    }
231
232    pub fn variables_mut(&mut self) -> impl Iterator<Item = &mut TypeVariable> {
233        self.variables.iter_mut()
234    }
235
236    pub fn add_to_variables<I>(&mut self, value: I)
237    where
238        I: Into<TypeVariable>,
239    {
240        self.variables.push(value.into())
241    }
242
243    pub fn extend_variables<I>(&mut self, extension: I)
244    where
245        I: IntoIterator<Item = TypeVariable>,
246    {
247        self.variables.extend(extension)
248    }
249}
250
251// ------------------------------------------------------------------------------------------------
252// Implementations ❱ Definitions ❱ TypeVariable
253// ------------------------------------------------------------------------------------------------
254
255impl HasName for TypeVariable {
256    fn name(&self) -> &Identifier {
257        &self.name
258    }
259
260    fn set_name(&mut self, name: Identifier) {
261        self.name = name;
262    }
263}
264
265impl HasSourceSpan for TypeVariable {
266    fn with_source_span(self, span: Span) -> Self {
267        let mut self_mut = self;
268        self_mut.span = Some(span);
269        self_mut
270    }
271
272    fn source_span(&self) -> Option<&Span> {
273        self.span.as_ref()
274    }
275
276    fn set_source_span(&mut self, span: Span) {
277        self.span = Some(span);
278    }
279
280    fn unset_source_span(&mut self) {
281        self.span = None;
282    }
283}
284
285impl TypeVariable {
286    // --------------------------------------------------------------------------------------------
287    // Constructors
288    // --------------------------------------------------------------------------------------------
289
290    pub const fn new(name: Identifier) -> Self {
291        Self {
292            span: None,
293            name,
294            cardinality: None,
295            restrictions: Vec::new(),
296        }
297    }
298
299    pub fn with_cardinality(self, cardinality: FunctionCardinality) -> Self {
300        Self {
301            cardinality: Some(cardinality),
302            ..self
303        }
304    }
305
306    pub fn with_restrictions<I>(self, restrictions: I) -> Self
307    where
308        I: IntoIterator<Item = TypeClassReference>,
309    {
310        Self {
311            restrictions: Vec::from_iter(restrictions),
312            ..self
313        }
314    }
315
316    // --------------------------------------------------------------------------------------------
317    // Fields
318    // --------------------------------------------------------------------------------------------
319
320    pub const fn has_cardinality(&self) -> bool {
321        self.cardinality.is_some()
322    }
323
324    pub const fn cardinality(&self) -> Option<&FunctionCardinality> {
325        self.cardinality.as_ref()
326    }
327
328    pub fn set_cardinality(&mut self, cardinality: FunctionCardinality) {
329        self.cardinality = Some(cardinality);
330    }
331
332    pub fn unset_cardinality(&mut self) {
333        self.cardinality = None;
334    }
335
336    // --------------------------------------------------------------------------------------------
337
338    pub fn has_restrictions(&self) -> bool {
339        !self.restrictions.is_empty()
340    }
341
342    pub fn restrictions_len(&self) -> usize {
343        self.restrictions.len()
344    }
345
346    pub fn restrictions(&self) -> impl Iterator<Item = &TypeClassReference> {
347        self.restrictions.iter()
348    }
349
350    pub fn restrictions_mut(&mut self) -> impl Iterator<Item = &mut TypeClassReference> {
351        self.restrictions.iter_mut()
352    }
353
354    pub fn add_to_restrictions<I>(&mut self, value: I)
355    where
356        I: Into<TypeClassReference>,
357    {
358        self.restrictions.push(value.into())
359    }
360
361    pub fn extend_restrictions<I>(&mut self, extension: I)
362    where
363        I: IntoIterator<Item = TypeClassReference>,
364    {
365        self.restrictions.extend(extension)
366    }
367}
368
369// ------------------------------------------------------------------------------------------------
370// Implementations ❱ Definitions ❱ TypeClassReference
371// ------------------------------------------------------------------------------------------------
372
373impl HasSourceSpan for TypeClassReference {
374    fn with_source_span(self, span: Span) -> Self {
375        let mut self_mut = self;
376        self_mut.span = Some(span);
377        self_mut
378    }
379
380    fn source_span(&self) -> Option<&Span> {
381        self.span.as_ref()
382    }
383
384    fn set_source_span(&mut self, span: Span) {
385        self.span = Some(span);
386    }
387
388    fn unset_source_span(&mut self) {
389        self.span = None;
390    }
391}
392
393impl TypeClassReference {
394    // --------------------------------------------------------------------------------------------
395    // Constructors
396    // --------------------------------------------------------------------------------------------
397
398    pub const fn new(name: IdentifierReference) -> Self {
399        Self {
400            span: None,
401            name,
402            arguments: Vec::new(),
403        }
404    }
405
406    pub fn with_arguments<I>(self, arguments: I) -> Self
407    where
408        I: IntoIterator<Item = TypeClassArgument>,
409    {
410        Self {
411            arguments: Vec::from_iter(arguments),
412            ..self
413        }
414    }
415
416    // --------------------------------------------------------------------------------------------
417    // Fields
418    // --------------------------------------------------------------------------------------------
419
420    pub const fn name(&self) -> &IdentifierReference {
421        &self.name
422    }
423
424    pub fn set_name(&mut self, name: IdentifierReference) {
425        self.name = name;
426    }
427
428    // --------------------------------------------------------------------------------------------
429
430    pub fn has_arguments(&self) -> bool {
431        !self.arguments.is_empty()
432    }
433
434    pub fn arguments_len(&self) -> usize {
435        self.arguments.len()
436    }
437
438    pub fn arguments(&self) -> impl Iterator<Item = &TypeClassArgument> {
439        self.arguments.iter()
440    }
441
442    pub fn arguments_mut(&mut self) -> impl Iterator<Item = &mut TypeClassArgument> {
443        self.arguments.iter_mut()
444    }
445
446    pub fn add_to_arguments<I>(&mut self, value: I)
447    where
448        I: Into<TypeClassArgument>,
449    {
450        self.arguments.push(value.into())
451    }
452
453    pub fn extend_arguments<I>(&mut self, extension: I)
454    where
455        I: IntoIterator<Item = TypeClassArgument>,
456    {
457        self.arguments.extend(extension)
458    }
459}
460
461// ------------------------------------------------------------------------------------------------
462// Implementations ❱ Definitions ❱ TypeClassArgument
463// ------------------------------------------------------------------------------------------------
464
465impl TypeClassArgument {
466    // --------------------------------------------------------------------------------------------
467    // Variants
468    // --------------------------------------------------------------------------------------------
469
470    pub const fn is_wildcard(&self) -> bool {
471        matches!(self, Self::Wildcard)
472    }
473
474    pub const fn is_reference(&self) -> bool {
475        matches!(self, Self::Reference(_))
476    }
477
478    pub const fn as_reference(&self) -> Option<&TypeClassReference> {
479        match self {
480            Self::Reference(v) => Some(v),
481            _ => None,
482        }
483    }
484}
485
486// ------------------------------------------------------------------------------------------------
487// Implementations ❱ Definitions ❱ TypeClassBody
488// ------------------------------------------------------------------------------------------------
489
490impl HasSourceSpan for TypeClassBody {
491    fn with_source_span(self, span: Span) -> Self {
492        let mut self_mut = self;
493        self_mut.span = Some(span);
494        self_mut
495    }
496
497    fn source_span(&self) -> Option<&Span> {
498        self.span.as_ref()
499    }
500
501    fn set_source_span(&mut self, span: Span) {
502        self.span = Some(span);
503    }
504
505    fn unset_source_span(&mut self) {
506        self.span = None;
507    }
508}
509
510impl HasAnnotations for TypeClassBody {
511    fn has_annotations(&self) -> bool {
512        !self.annotations.is_empty()
513    }
514
515    fn annotation_count(&self) -> usize {
516        self.annotations.len()
517    }
518
519    fn annotations(&self) -> impl Iterator<Item = &Annotation> {
520        self.annotations.iter()
521    }
522
523    fn annotations_mut(&mut self) -> impl Iterator<Item = &mut Annotation> {
524        self.annotations.iter_mut()
525    }
526
527    fn add_to_annotations<I>(&mut self, value: I)
528    where
529        I: Into<Annotation>,
530    {
531        self.annotations.push(value.into())
532    }
533
534    fn extend_annotations<I>(&mut self, extension: I)
535    where
536        I: IntoIterator<Item = Annotation>,
537    {
538        self.annotations.extend(extension.into_iter())
539    }
540}
541
542impl TypeClassBody {
543    // --------------------------------------------------------------------------------------------
544    // Constructors
545    // --------------------------------------------------------------------------------------------
546
547    pub fn with_methods<I>(self, methods: I) -> Self
548    where
549        I: IntoIterator<Item = MethodDef>,
550    {
551        Self {
552            methods: methods
553                .into_iter()
554                .map(|elem| (elem.name().clone(), elem))
555                .collect(),
556            ..self
557        }
558    }
559
560    // --------------------------------------------------------------------------------------------
561    // Fields
562    // --------------------------------------------------------------------------------------------
563
564    pub fn has_methods(&self) -> bool {
565        !self.methods.is_empty()
566    }
567
568    pub fn method_count(&self) -> usize {
569        self.methods.len()
570    }
571
572    pub fn contains_method(&self, name: &Identifier) -> bool {
573        self.methods.contains_key(name)
574    }
575
576    pub fn method(&self, name: &Identifier) -> Option<&MethodDef> {
577        self.methods.get(name)
578    }
579
580    pub fn method_mut(&mut self, name: &Identifier) -> Option<&mut MethodDef> {
581        self.methods.get_mut(name)
582    }
583
584    pub fn methods(&self) -> impl Iterator<Item = &MethodDef> {
585        self.methods.values()
586    }
587
588    pub fn methods_mut(&mut self) -> impl Iterator<Item = &mut MethodDef> {
589        self.methods.values_mut()
590    }
591
592    pub fn method_names(&self) -> impl Iterator<Item = &Identifier> {
593        self.methods.keys()
594    }
595
596    pub fn add_to_methods(&mut self, value: MethodDef) -> Option<MethodDef> {
597        self.methods.insert(value.name().clone(), value)
598    }
599
600    pub fn extend_methods<I>(&mut self, extension: I)
601    where
602        I: IntoIterator<Item = MethodDef>,
603    {
604        self.methods.extend(
605            extension
606                .into_iter()
607                .map(|elem| (elem.name().clone(), elem)),
608        )
609    }
610}
611
612// ------------------------------------------------------------------------------------------------
613// Implementations ❱ Definitions ❱ MethodDef
614// ------------------------------------------------------------------------------------------------
615
616impl HasAnnotations for MethodDef {
617    fn has_annotations(&self) -> bool {
618        !self.annotations.is_empty()
619    }
620
621    fn annotation_count(&self) -> usize {
622        self.annotations.len()
623    }
624
625    fn annotations(&self) -> impl Iterator<Item = &Annotation> {
626        self.annotations.iter()
627    }
628
629    fn annotations_mut(&mut self) -> impl Iterator<Item = &mut Annotation> {
630        self.annotations.iter_mut()
631    }
632
633    fn add_to_annotations<I>(&mut self, value: I)
634    where
635        I: Into<Annotation>,
636    {
637        self.annotations.push(value.into())
638    }
639
640    fn extend_annotations<I>(&mut self, extension: I)
641    where
642        I: IntoIterator<Item = Annotation>,
643    {
644        self.annotations.extend(extension.into_iter())
645    }
646}
647
648impl HasName for MethodDef {
649    fn name(&self) -> &Identifier {
650        &self.name
651    }
652
653    fn set_name(&mut self, name: Identifier) {
654        self.name = name;
655    }
656}
657
658impl HasOptionalBody for MethodDef {
659    type Body = ConstraintSentence;
660
661    fn body(&self) -> Option<&Self::Body> {
662        self.body.as_ref()
663    }
664
665    fn body_mut(&mut self) -> Option<&mut Self::Body> {
666        self.body.as_mut()
667    }
668
669    fn set_body(&mut self, body: Self::Body) {
670        self.body = Some(body);
671    }
672
673    fn unset_body(&mut self) {
674        self.body = None;
675    }
676}
677
678impl HasSourceSpan for MethodDef {
679    fn with_source_span(self, span: Span) -> Self {
680        let mut self_mut = self;
681        self_mut.span = Some(span);
682        self_mut
683    }
684
685    fn source_span(&self) -> Option<&Span> {
686        self.span.as_ref()
687    }
688
689    fn set_source_span(&mut self, span: Span) {
690        self.span = Some(span);
691    }
692
693    fn unset_source_span(&mut self) {
694        self.span = None;
695    }
696}
697
698impl MethodDef {
699    // --------------------------------------------------------------------------------------------
700    // Constructors
701    // --------------------------------------------------------------------------------------------
702
703    pub const fn new(name: Identifier, signature: FunctionSignature) -> Self {
704        Self {
705            span: None,
706            name,
707            signature,
708            body: None,
709            annotations: Vec::new(),
710        }
711    }
712
713    pub fn with_body(self, body: ConstraintSentence) -> Self {
714        Self {
715            body: Some(body),
716            ..self
717        }
718    }
719
720    // --------------------------------------------------------------------------------------------
721    // Fields
722    // --------------------------------------------------------------------------------------------
723
724    pub const fn signature(&self) -> &FunctionSignature {
725        &self.signature
726    }
727
728    pub fn set_signature(&mut self, signature: FunctionSignature) {
729        self.signature = signature;
730    }
731}