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::Annotation;
14use crate::model::check::Validate;
15use crate::model::constraints::{ConstraintSentence, FunctionCardinality, FunctionSignature};
16use crate::model::identifiers::{Identifier, IdentifierReference};
17use crate::model::{HasName, References, Span};
18use crate::store::ModuleStore;
19
20use sdml_errors::diagnostics::functions::IdentifierCaseConvention;
21#[cfg(feature = "serde")]
22use serde::{Deserialize, Serialize};
23
24// ------------------------------------------------------------------------------------------------
25// Public Types
26// ------------------------------------------------------------------------------------------------
27
28/// Corresponds to the grammar rule `type_class_def`.
29#[derive(Clone, Debug)]
30#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
31pub struct TypeClassDef {
32    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
33    span: Option<Box<Span>>,
34    name: Identifier,
35    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Vec::is_empty"))]
36    variables: Vec<TypeVariable>, // assert 1..
37    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
38    body: Option<TypeClassBody>,
39}
40
41/// Corresponds to the grammar rule `type_variable`.
42#[derive(Clone, Debug)]
43#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
44pub struct TypeVariable {
45    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
46    span: Option<Box<Span>>,
47    name: Identifier,
48    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
49    cardinality: Option<FunctionCardinality>,
50    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Vec::is_empty"))]
51    restrictions: Vec<TypeClassReference>,
52}
53
54/// Corresponds to the grammar rule `type_class_reference`.
55#[derive(Clone, Debug)]
56#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
57pub struct TypeClassReference {
58    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
59    span: Option<Box<Span>>,
60    name: IdentifierReference,
61    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Vec::is_empty"))]
62    arguments: Vec<TypeClassArgument>, // 0..
63}
64
65/// Corresponds to the grammar rule `type_class_arguments`.
66#[derive(Clone, Debug)]
67#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
68pub enum TypeClassArgument {
69    Wildcard,
70    Reference(Box<TypeClassReference>),
71}
72
73/// Corresponds to the grammar rule `type_class_body`.
74#[derive(Clone, Debug, Default)]
75#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
76pub struct TypeClassBody {
77    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
78    span: Option<Box<Span>>,
79    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Vec::is_empty"))]
80    annotations: Vec<Annotation>,
81    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Vec::is_empty"))]
82    methods: Vec<MethodDef>,
83}
84
85/// Corresponds to the grammar rule `method_def`.
86#[derive(Clone, Debug)]
87#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
88pub struct MethodDef {
89    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
90    span: Option<Box<Span>>,
91    name: Identifier,
92    signature: FunctionSignature,
93    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
94    body: Option<ConstraintSentence>,
95    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Vec::is_empty"))]
96    annotations: Vec<Annotation>,
97}
98
99// ------------------------------------------------------------------------------------------------
100// Implementations
101// ------------------------------------------------------------------------------------------------
102
103impl_has_name_for!(TypeClassDef);
104
105impl_has_optional_body_for!(TypeClassDef, TypeClassBody);
106
107impl_has_source_span_for!(TypeClassDef);
108
109impl_annotation_builder!(TypeClassDef, optional body);
110
111impl_maybe_incomplete_for!(TypeClassDef; exists body);
112
113impl References for TypeClassDef {
114    fn referenced_types<'a>(
115        &'a self,
116        _names: &mut std::collections::HashSet<&'a IdentifierReference>,
117    ) {
118    }
119
120    fn referenced_annotations<'a>(
121        &'a self,
122        _names: &mut std::collections::HashSet<&'a IdentifierReference>,
123    ) {
124    }
125}
126
127impl Validate for TypeClassDef {
128    fn validate(
129        &self,
130        top: &crate::model::modules::Module,
131        _cache: &impl ModuleStore,
132        loader: &impl ModuleLoader,
133        _check_constraints: bool,
134    ) {
135        self.name()
136            .validate(top, loader, Some(IdentifierCaseConvention::TypeDefinition));
137        todo!()
138    }
139}
140
141impl TypeClassDef {
142    // --------------------------------------------------------------------------------------------
143    // TypeClassDef :: Constructors
144    // --------------------------------------------------------------------------------------------
145
146    pub fn new<I>(name: Identifier, variables: I) -> Self
147    where
148        I: IntoIterator<Item = TypeVariable>,
149    {
150        Self {
151            span: None,
152            name,
153            variables: Vec::from_iter(variables),
154            body: None,
155        }
156    }
157
158    // --------------------------------------------------------------------------------------------
159    // TypeClassDef :: Fields
160    // --------------------------------------------------------------------------------------------
161
162    get_and_set_vec!(
163        pub
164        has has_variables,
165        variables_len,
166        variables,
167        variables_mut,
168        add_to_variables,
169        extend_variables
170            => variables, TypeVariable
171    );
172}
173
174// ------------------------------------------------------------------------------------------------
175
176impl_has_name_for!(TypeVariable);
177
178impl_has_source_span_for!(TypeVariable);
179
180impl TypeVariable {
181    // --------------------------------------------------------------------------------------------
182    // TypeVariable :: Constructors
183    // --------------------------------------------------------------------------------------------
184
185    pub const fn new(name: Identifier) -> Self {
186        Self {
187            span: None,
188            name,
189            cardinality: None,
190            restrictions: Vec::new(),
191        }
192    }
193
194    pub fn with_cardinality(self, cardinality: FunctionCardinality) -> Self {
195        Self {
196            cardinality: Some(cardinality),
197            ..self
198        }
199    }
200
201    pub fn with_restrictions<I>(self, restrictions: I) -> Self
202    where
203        I: IntoIterator<Item = TypeClassReference>,
204    {
205        Self {
206            restrictions: Vec::from_iter(restrictions),
207            ..self
208        }
209    }
210
211    // --------------------------------------------------------------------------------------------
212    // TypeVariable :: Fields
213    // --------------------------------------------------------------------------------------------
214
215    get_and_set!(pub cardinality, set_cardinality, unset_cardinality => optional has_cardinality, FunctionCardinality);
216
217    get_and_set_vec!(
218        pub
219        has has_restrictions,
220        restrictions_len,
221        restrictions,
222        restrictions_mut,
223        add_to_restrictions,
224        extend_restrictions
225            => restrictions, TypeClassReference
226    );
227}
228
229// ------------------------------------------------------------------------------------------------
230
231impl_has_source_span_for!(TypeClassReference);
232
233impl TypeClassReference {
234    // --------------------------------------------------------------------------------------------
235    // TypeClassReference :: Constructors
236    // --------------------------------------------------------------------------------------------
237
238    pub const fn new(name: IdentifierReference) -> Self {
239        Self {
240            span: None,
241            name,
242            arguments: Vec::new(),
243        }
244    }
245
246    pub fn with_arguments<I>(self, arguments: I) -> Self
247    where
248        I: IntoIterator<Item = TypeClassArgument>,
249    {
250        Self {
251            arguments: Vec::from_iter(arguments),
252            ..self
253        }
254    }
255
256    // --------------------------------------------------------------------------------------------
257    // TypeClassReference :: Fields
258    // --------------------------------------------------------------------------------------------
259
260    get_and_set!(pub name, set_name => IdentifierReference);
261
262    get_and_set_vec!(
263        pub
264        has has_arguments,
265        arguments_len,
266        arguments,
267        arguments_mut,
268        add_to_arguments,
269        extend_arguments
270            => arguments, TypeClassArgument
271    );
272}
273
274// ------------------------------------------------------------------------------------------------
275
276impl TypeClassArgument {
277    // --------------------------------------------------------------------------------------------
278    // TypeClassArgument :: Variants
279    // --------------------------------------------------------------------------------------------
280
281    is_variant!(Wildcard  => is_wildcard);
282
283    is_as_variant!(Reference (TypeClassReference) => is_reference, as_reference);
284}
285
286// ------------------------------------------------------------------------------------------------
287
288impl_has_source_span_for!(TypeClassBody);
289
290impl_has_annotations_for!(TypeClassBody);
291
292impl TypeClassBody {
293    // --------------------------------------------------------------------------------------------
294    // TypeClassBody :: Constructors
295    // --------------------------------------------------------------------------------------------
296
297    pub fn with_methods<I>(self, methods: I) -> Self
298    where
299        I: IntoIterator<Item = MethodDef>,
300    {
301        Self {
302            methods: Vec::from_iter(methods),
303            ..self
304        }
305    }
306
307    // --------------------------------------------------------------------------------------------
308    // TypeClassBody :: Fields
309    // --------------------------------------------------------------------------------------------
310
311    get_and_set_vec!(
312        pub
313        has has_methods,
314        methods_len,
315        methods,
316        methods_mut,
317        add_to_methods,
318        extend_methods
319            => methods, MethodDef
320    );
321}
322
323// ------------------------------------------------------------------------------------------------
324
325impl_has_annotations_for!(MethodDef);
326
327impl_has_name_for!(MethodDef);
328
329impl_has_optional_body_for!(MethodDef, ConstraintSentence);
330
331impl_has_source_span_for!(MethodDef);
332
333impl MethodDef {
334    // --------------------------------------------------------------------------------------------
335    // Constructors
336    // --------------------------------------------------------------------------------------------
337
338    pub const fn new(name: Identifier, signature: FunctionSignature) -> Self {
339        Self {
340            span: None,
341            name,
342            signature,
343            body: None,
344            annotations: Vec::new(),
345        }
346    }
347
348    pub fn with_body(self, body: ConstraintSentence) -> Self {
349        Self {
350            body: Some(body),
351            ..self
352        }
353    }
354
355    // --------------------------------------------------------------------------------------------
356    // Fields
357    // --------------------------------------------------------------------------------------------
358
359    get_and_set!(pub signature, set_signature => FunctionSignature);
360}