sdml_core/model/constraints/formal/
functions.rs1use 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::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#[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<Box<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<Box<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<Box<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<Box<Span>>,
51 target_cardinality: FunctionCardinality,
52 target_type: FunctionTypeReference,
53}
54
55#[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<Box<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 struct FunctionTypeReference {
72 optional: bool,
73 inner: FunctionTypeReferenceInner,
74}
75
76#[derive(Clone, Debug)]
77#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
78pub enum FunctionTypeReferenceInner {
79 Wildcard,
80 Reference(IdentifierReference),
81 MappingType(MappingType),
83}
84
85impl_has_body_for!(FunctionDef, ConstraintSentence);
90
91impl_has_source_span_for!(FunctionDef);
92
93impl FunctionDef {
94 pub const fn new(signature: FunctionSignature, body: ConstraintSentence) -> Self {
99 Self {
100 span: None,
101 signature,
102 body,
103 }
104 }
105
106 get_and_set!(pub signature, set_signature => FunctionSignature);
111}
112
113impl_has_source_span_for!(FunctionSignature);
116
117impl FunctionSignature {
118 pub fn new(parameters: Vec<FunctionParameter>, target_type: FunctionType) -> Self {
123 Self {
124 span: Default::default(),
125 parameters,
126 target_type,
127 }
128 }
129
130 get_and_set_vec!(
135 pub
136 has has_parameters,
137 parameters_len,
138 parameters,
139 parameters_mut,
140 add_to_parameters,
141 extend_parameters
142 => parameters, FunctionParameter
143 );
144
145 get_and_set!(pub target_type, set_target_type => FunctionType);
146}
147
148impl_has_name_for!(FunctionParameter);
151
152impl_has_source_span_for!(FunctionParameter);
153
154impl FunctionParameter {
155 pub const fn new(name: Identifier, target_type: FunctionType) -> Self {
160 Self {
161 span: None,
162 name,
163 target_type,
164 }
165 }
166
167 get_and_set!(pub target_type, set_target_type => FunctionType);
172}
173
174impl_has_source_span_for!(FunctionType);
177
178impl FunctionType {
179 pub fn new(
184 target_cardinality: FunctionCardinality,
185 target_type: FunctionTypeReference,
186 ) -> Self {
187 Self {
188 span: Default::default(),
189 target_cardinality,
190 target_type,
191 }
192 }
193
194 pub fn with_wildcard_cardinality(self) -> Self {
199 Self {
200 target_cardinality: FunctionCardinality::new_wildcard(),
201 ..self
202 }
203 }
204
205 pub fn with_target_cardinality(self, target_cardinality: FunctionCardinality) -> Self {
206 Self {
207 target_cardinality,
208 ..self
209 }
210 }
211
212 get_and_set!(pub target_cardinality, set_target_cardinality => FunctionCardinality);
213
214 pub fn with_target_type(self, target_type: FunctionTypeReference) -> Self {
215 Self {
216 target_type,
217 ..self
218 }
219 }
220
221 get_and_set!(pub target_type, set_target_type => FunctionTypeReference);
222}
223
224impl Display for FunctionCardinality {
227 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
228 write!(
229 f,
230 "{{{}{}{}}}",
231 self.ordering.map(|c| format!("{} ", c)).unwrap_or_default(),
232 self.uniqueness
233 .map(|c| format!("{} ", c))
234 .unwrap_or_default(),
235 if let Some(range) = &self.range {
236 range.to_string()
237 } else {
238 KW_WILDCARD.to_string()
239 }
240 )
241 }
242}
243
244impl_has_source_span_for!(FunctionCardinality);
245
246impl Validate for FunctionCardinality {
247 fn validate(
248 &self,
249 _top: &Module,
250 _cache: &impl ModuleStore,
251 _loader: &impl ModuleLoader,
252 _check_constraints: bool,
253 ) {
254 todo!()
255 }
256}
257
258impl FunctionCardinality {
259 pub const fn new(
264 ordering: Option<Ordering>,
265 uniqueness: Option<Uniqueness>,
266 range: Option<CardinalityRange>,
267 ) -> Self {
268 Self {
269 span: None,
270 ordering,
271 uniqueness,
272 range,
273 }
274 }
275
276 pub const fn new_range(min: u32, max: u32) -> Self {
277 Self {
278 span: None,
279 ordering: None,
280 uniqueness: None,
281 range: Some(CardinalityRange::new_range(min, max)),
282 }
283 }
284
285 pub const fn new_unbounded(min: u32) -> Self {
286 Self {
287 span: None,
288 ordering: None,
289 uniqueness: None,
290 range: Some(CardinalityRange::new_unbounded(min)),
291 }
292 }
293
294 pub const fn new_single(min_and_max: u32) -> Self {
295 Self {
296 span: None,
297 ordering: None,
298 uniqueness: None,
299 range: Some(CardinalityRange::new_single(min_and_max)),
300 }
301 }
302
303 pub const fn new_wildcard() -> Self {
304 Self {
305 span: None,
306 ordering: None,
307 uniqueness: None,
308 range: None,
309 }
310 }
311
312 #[inline(always)]
313 pub const fn one() -> Self {
314 Self::new_single(1)
315 }
316
317 #[inline(always)]
318 pub const fn zero_or_one() -> Self {
319 Self::new_range(0, 1)
320 }
321
322 #[inline(always)]
323 pub const fn one_or_more() -> Self {
324 Self::new_unbounded(1)
325 }
326
327 #[inline(always)]
328 pub const fn zero_or_more() -> Self {
329 Self::new_unbounded(0)
330 }
331
332 pub fn with_ordering(self, ordering: Ordering) -> Self {
337 Self {
338 ordering: Some(ordering),
339 ..self
340 }
341 }
342
343 get_and_set!(pub ordering, set_ordering, unset_ordering => optional copy has_ordering, Ordering);
344
345 #[inline(always)]
346 pub fn is_ordered(&self) -> Option<bool> {
347 self.ordering().map(|o| o == Ordering::Ordered)
348 }
349
350 #[inline(always)]
353 pub fn with_uniqueness(self, uniqueness: Uniqueness) -> Self {
354 Self {
355 uniqueness: Some(uniqueness),
356 ..self
357 }
358 }
359
360 get_and_set!(pub uniqueness, set_uniqueness, unset_uniqueness => optional copy has_uniqueness, Uniqueness);
361
362 #[inline(always)]
363 pub fn is_unique(&self) -> Option<bool> {
364 self.uniqueness().map(|u| u == Uniqueness::Unique)
365 }
366
367 get_and_set!(pub range, set_range, unset_range => optional has_range, CardinalityRange);
370
371 pub fn is_wildcard(&self) -> bool {
372 self.range.is_none()
373 }
374}
375
376impl From<FunctionTypeReferenceInner> for FunctionTypeReference {
379 fn from(inner: FunctionTypeReferenceInner) -> Self {
380 Self {
381 optional: false,
382 inner,
383 }
384 }
385}
386
387impl AsRef<FunctionTypeReferenceInner> for FunctionTypeReference {
388 fn as_ref(&self) -> &FunctionTypeReferenceInner {
389 &self.inner
390 }
391}
392
393impl FunctionTypeReference {
394 pub fn optional(inner: FunctionTypeReferenceInner) -> Self {
399 Self {
400 optional: true,
401 inner,
402 }
403 }
404
405 pub fn is_optional(&self) -> bool {
410 self.optional
411 }
412
413 pub fn inner(&self) -> &FunctionTypeReferenceInner {
414 &self.inner
415 }
416}
417
418impl From<IdentifierReference> for FunctionTypeReferenceInner {
421 fn from(value: IdentifierReference) -> Self {
422 Self::Reference(value)
423 }
424}
425
426impl From<MappingType> for FunctionTypeReferenceInner {
427 fn from(value: MappingType) -> Self {
428 Self::MappingType(value)
429 }
430}
431
432impl FunctionTypeReferenceInner {
433 is_as_variant!(Reference (IdentifierReference) => is_type_reference, as_type_reference);
438
439 is_as_variant!(MappingType (MappingType) => is_mapping_type, as_mapping_type);
440
441 is_variant!(Wildcard => is_wildcard);
442}