sdml_core/model/definitions/
classes.rs

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