sdml_core/model/definitions/
classes.rs1use 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#[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>, #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
38 body: Option<TypeClassBody>,
39}
40
41#[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#[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>, }
64
65#[derive(Clone, Debug)]
67#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
68pub enum TypeClassArgument {
69 Wildcard,
70 Reference(Box<TypeClassReference>),
71}
72
73#[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#[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
99impl_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 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 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
174impl_has_name_for!(TypeVariable);
177
178impl_has_source_span_for!(TypeVariable);
179
180impl TypeVariable {
181 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 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
229impl_has_source_span_for!(TypeClassReference);
232
233impl TypeClassReference {
234 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 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
274impl TypeClassArgument {
277 is_variant!(Wildcard => is_wildcard);
282
283 is_as_variant!(Reference (TypeClassReference) => is_reference, as_reference);
284}
285
286impl_has_source_span_for!(TypeClassBody);
289
290impl_has_annotations_for!(TypeClassBody);
291
292impl TypeClassBody {
293 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 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
323impl_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 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 get_and_set!(pub signature, set_signature => FunctionSignature);
360}