sdml_core/model/members/
cardinality.rs

1use crate::error::Error;
2use crate::load::ModuleLoader;
3use crate::model::check::Validate;
4use crate::model::modules::Module;
5use crate::model::{HasSourceSpan, Span};
6use crate::store::ModuleStore;
7use crate::syntax::{
8    KW_ORDERING_ORDERED, KW_ORDERING_UNORDERED, KW_UNIQUENESS_NONUNIQUE, KW_UNIQUENESS_UNIQUE,
9};
10use std::fmt::{Debug, Display};
11use std::str::FromStr;
12
13#[cfg(feature = "serde")]
14use serde::{Deserialize, Serialize};
15
16// ------------------------------------------------------------------------------------------------
17// Public Types ❱ Members ❱ Cardinality
18// ------------------------------------------------------------------------------------------------
19
20pub trait HasCardinality {
21    fn target_cardinality(&self) -> &Cardinality;
22
23    fn set_target_cardinality(&mut self, target_cardinality: Cardinality);
24}
25
26/// Corresponds to the grammar rule `cardinality`.
27#[derive(Clone, Debug, Default, PartialEq, Eq)]
28#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
29pub struct Cardinality {
30    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
31    span: Option<Span>,
32    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
33    ordering: Option<Ordering>,
34    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
35    uniqueness: Option<Uniqueness>,
36    range: CardinalityRange,
37}
38
39pub const DEFAULT_CARDINALITY: Cardinality = Cardinality::one();
40
41pub const TYPE_BAG_CARDINALITY: Cardinality = Cardinality::zero_or_more();
42pub const TYPE_LIST_CARDINALITY: Cardinality =
43    Cardinality::zero_or_more().with_ordering(Some(Ordering::Ordered));
44pub const TYPE_SET_CARDINALITY: Cardinality =
45    Cardinality::zero_or_more().with_uniqueness(Some(Uniqueness::Unique));
46pub const TYPE_ORDERED_SET_CARDINALITY: Cardinality = Cardinality::zero_or_more()
47    .with_ordering(Some(Ordering::Ordered))
48    .with_uniqueness(Some(Uniqueness::Unique));
49pub const TYPE_MAYBE_CARDINALITY: Cardinality = Cardinality::zero_or_one();
50
51#[derive(Clone, Debug, Default, PartialEq, Eq)]
52#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
53pub struct CardinalityRange {
54    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
55    span: Option<Span>,
56    min: u32,
57    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
58    max: Option<u32>,
59}
60
61pub const DEFAULT_CARDINALITY_RANGE: CardinalityRange = CardinalityRange::one();
62
63/// Corresponds to the grammar rule `sequence_ordering`.
64#[derive(Clone, Copy, Debug, PartialEq, Eq)]
65#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
66pub enum Ordering {
67    Ordered,
68    Unordered,
69}
70
71/// Corresponds to the grammar rule `sequence_uniqueness`.
72#[derive(Clone, Copy, Debug, PartialEq, Eq)]
73#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
74pub enum Uniqueness {
75    Unique,
76    Nonunique,
77}
78
79#[derive(Clone, Copy, Debug, PartialEq, Eq)]
80pub enum PseudoSequenceType {
81    Maybe,
82    Bag,
83    List,
84    Set,
85    UnorderedSet,
86}
87
88// ------------------------------------------------------------------------------------------------
89// Implementations ❱ Members ❱ Cardinality
90// ------------------------------------------------------------------------------------------------
91
92impl From<&u32> for Cardinality {
93    fn from(value: &u32) -> Self {
94        Self::new_single(*value)
95    }
96}
97
98impl From<u32> for Cardinality {
99    fn from(value: u32) -> Self {
100        Self::new_single(value)
101    }
102}
103
104impl From<CardinalityRange> for Cardinality {
105    fn from(range: CardinalityRange) -> Self {
106        Self::new(None, None, range)
107    }
108}
109
110impl From<&CardinalityRange> for Cardinality {
111    fn from(range: &CardinalityRange) -> Self {
112        Self::new(None, None, range.clone())
113    }
114}
115
116impl Display for Cardinality {
117    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
118        write!(
119            f,
120            "{{{}{}{}..{}}}",
121            self.ordering.map(|c| format!("{} ", c)).unwrap_or_default(),
122            self.uniqueness
123                .map(|c| format!("{} ", c))
124                .unwrap_or_default(),
125            self.min_occurs(),
126            self.max_occurs().map(|i| i.to_string()).unwrap_or_default()
127        )
128    }
129}
130
131impl HasSourceSpan for Cardinality {
132    fn with_source_span(self, span: Span) -> Self {
133        let mut self_mut = self;
134        self_mut.span = Some(span);
135        self_mut
136    }
137
138    fn source_span(&self) -> Option<&Span> {
139        self.span.as_ref()
140    }
141
142    fn set_source_span(&mut self, span: Span) {
143        self.span = Some(span);
144    }
145
146    fn unset_source_span(&mut self) {
147        self.span = None;
148    }
149}
150
151impl Validate for Cardinality {
152    fn validate(
153        &self,
154        top: &Module,
155        cache: &impl ModuleStore,
156        loader: &impl ModuleLoader,
157        check_constraints: bool,
158    ) {
159        self.range.validate(top, cache, loader, check_constraints);
160    }
161}
162
163impl Cardinality {
164    // --------------------------------------------------------------------------------------------
165    // Constructors
166    // --------------------------------------------------------------------------------------------
167
168    pub const fn new(
169        ordering: Option<Ordering>,
170        uniqueness: Option<Uniqueness>,
171        range: CardinalityRange,
172    ) -> Self {
173        Self {
174            span: None,
175            ordering,
176            uniqueness,
177            range,
178        }
179    }
180
181    pub const fn new_range(min: u32, max: u32) -> Self {
182        Self {
183            span: None,
184            ordering: None,
185            uniqueness: None,
186            range: CardinalityRange::new_range(min, max),
187        }
188    }
189
190    pub const fn new_unbounded(min: u32) -> Self {
191        Self {
192            span: None,
193            ordering: None,
194            uniqueness: None,
195            range: CardinalityRange::new_unbounded(min),
196        }
197    }
198
199    pub const fn new_single(min_and_max: u32) -> Self {
200        Self {
201            span: None,
202            ordering: None,
203            uniqueness: None,
204            range: CardinalityRange::new_single(min_and_max),
205        }
206    }
207
208    #[inline(always)]
209    pub const fn one() -> Self {
210        Self::new_single(1)
211    }
212
213    #[inline(always)]
214    pub const fn zero_or_one() -> Self {
215        Self::new_range(0, 1)
216    }
217
218    #[inline(always)]
219    pub const fn one_or_more() -> Self {
220        Self::new_unbounded(1)
221    }
222
223    #[inline(always)]
224    pub const fn zero_or_more() -> Self {
225        Self::new_unbounded(0)
226    }
227
228    // --------------------------------------------------------------------------------------------
229    // Fields
230    // --------------------------------------------------------------------------------------------
231
232    pub const fn with_ordering(self, ordering: Option<Ordering>) -> Self {
233        Self { ordering, ..self }
234    }
235
236    #[inline(always)]
237    pub fn ordering(&self) -> Option<Ordering> {
238        self.ordering
239    }
240
241    #[inline(always)]
242    pub fn set_ordering(&mut self, ordering: Ordering) {
243        self.ordering = Some(ordering);
244    }
245
246    #[inline(always)]
247    pub fn unset_ordering(&mut self) {
248        self.ordering = None;
249    }
250
251    #[inline(always)]
252    pub fn is_ordered(&self) -> Option<bool> {
253        self.ordering().map(|o| o == Ordering::Ordered)
254    }
255
256    // --------------------------------------------------------------------------------------------
257
258    #[inline(always)]
259    pub const fn with_uniqueness(self, uniqueness: Option<Uniqueness>) -> Self {
260        Self { uniqueness, ..self }
261    }
262
263    #[inline(always)]
264    pub fn uniqueness(&self) -> Option<Uniqueness> {
265        self.uniqueness
266    }
267
268    #[inline(always)]
269    pub fn set_uniqueness(&mut self, uniqueness: Uniqueness) {
270        self.uniqueness = Some(uniqueness);
271    }
272
273    #[inline(always)]
274    pub fn unset_uniqueness(&mut self) {
275        self.uniqueness = None;
276    }
277
278    #[inline(always)]
279    pub fn is_unique(&self) -> Option<bool> {
280        self.uniqueness().map(|u| u == Uniqueness::Unique)
281    }
282
283    // --------------------------------------------------------------------------------------------
284
285    pub fn range(&self) -> &CardinalityRange {
286        &self.range
287    }
288
289    pub fn set_range(&mut self, range: CardinalityRange) {
290        self.range = range;
291    }
292
293    // --------------------------------------------------------------------------------------------
294
295    #[inline(always)]
296    pub fn min_occurs(&self) -> u32 {
297        self.range.min_occurs()
298    }
299
300    #[inline(always)]
301    pub fn set_min_occurs(&mut self, min: u32) {
302        self.range.set_min_occurs(min);
303    }
304
305    // --------------------------------------------------------------------------------------------
306
307    #[inline(always)]
308    pub fn max_occurs(&self) -> Option<u32> {
309        self.range.max_occurs()
310    }
311
312    #[inline(always)]
313    pub fn set_max_occurs(&mut self, max: u32) {
314        self.range.set_max_occurs(max);
315    }
316
317    #[inline(always)]
318    pub fn unset_max_occurs(&mut self) {
319        self.range.unset_max_occurs();
320    }
321
322    // --------------------------------------------------------------------------------------------
323    // Helpers
324    // --------------------------------------------------------------------------------------------
325
326    #[inline(always)]
327    pub fn is_default(&self) -> bool {
328        self.ordering.is_none() && self.uniqueness.is_none() && self.range.is_exactly(1)
329    }
330
331    #[inline(always)]
332    pub fn is_optional(&self) -> bool {
333        self.range.is_optional()
334    }
335
336    #[inline(always)]
337    pub fn is_required(&self) -> bool {
338        !self.range.is_optional()
339    }
340
341    #[inline(always)]
342    pub fn is_range(&self) -> bool {
343        self.range.is_range()
344    }
345
346    #[inline(always)]
347    pub fn is_unbounded(&self) -> bool {
348        self.range.is_unbounded()
349    }
350
351    #[inline(always)]
352    pub fn is_exactly(&self, value: u32) -> bool {
353        self.range.is_exactly(value)
354    }
355
356    pub fn sequence_type(&self) -> PseudoSequenceType {
357        match (
358            self.is_ordered(),
359            self.is_unique(),
360            self.range.min_occurs(),
361            self.range.max_occurs().unwrap_or(self.range.min_occurs()),
362        ) {
363            (_, _, 0, 1) => PseudoSequenceType::Maybe,
364            (Some(true), Some(true), _, _) => PseudoSequenceType::UnorderedSet,
365            (Some(false), Some(true), _, _) => PseudoSequenceType::Set,
366            (Some(true), Some(false), _, _) => PseudoSequenceType::List,
367            _ => PseudoSequenceType::Bag,
368        }
369    }
370}
371
372// ------------------------------------------------------------------------------------------------
373// Implementations ❱ Members ❱ CardinalityRange
374// ------------------------------------------------------------------------------------------------
375
376impl From<u32> for CardinalityRange {
377    fn from(value: u32) -> Self {
378        Self::new_single(value)
379    }
380}
381
382impl Display for CardinalityRange {
383    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
384        write!(
385            f,
386            "{}..{}",
387            self.min,
388            self.max.map(|i| i.to_string()).unwrap_or_default()
389        )
390    }
391}
392
393impl HasSourceSpan for CardinalityRange {
394    fn with_source_span(self, span: Span) -> Self {
395        let mut self_mut = self;
396        self_mut.span = Some(span);
397        self_mut
398    }
399
400    fn source_span(&self) -> Option<&Span> {
401        self.span.as_ref()
402    }
403
404    fn set_source_span(&mut self, span: Span) {
405        self.span = Some(span);
406    }
407
408    fn unset_source_span(&mut self) {
409        self.span = None;
410    }
411}
412
413impl Validate for CardinalityRange {
414    fn validate(
415        &self,
416        _: &Module,
417        _: &impl ModuleStore,
418        _loader: &impl ModuleLoader,
419        _check_constraints: bool,
420    ) {
421        if let Some(max) = self.max {
422            if max < self.min {
423                panic!();
424            }
425        }
426    }
427}
428
429impl CardinalityRange {
430    // --------------------------------------------------------------------------------------------
431    // Constructors
432    // --------------------------------------------------------------------------------------------
433
434    pub const fn new_range(min: u32, max: u32) -> Self {
435        assert!(
436            max > 0 && max > min,
437            "Zero, or negative, cardinality range is not allowed."
438        );
439        Self {
440            span: None,
441            min,
442            max: Some(max),
443        }
444    }
445
446    pub const fn new_unbounded(min: u32) -> Self {
447        Self {
448            span: None,
449            min,
450            max: None,
451        }
452    }
453
454    pub const fn new_single(min_and_max: u32) -> Self {
455        assert!(
456            min_and_max != 0,
457            "Zero width cardinality range is not allowed."
458        );
459        Self {
460            span: None,
461            min: min_and_max,
462            max: Some(min_and_max),
463        }
464    }
465
466    #[inline(always)]
467    pub const fn one() -> Self {
468        Self::new_single(1)
469    }
470
471    #[inline(always)]
472    pub const fn zero_or_one() -> Self {
473        Self::new_range(0, 1)
474    }
475
476    #[inline(always)]
477    pub const fn one_or_more() -> Self {
478        Self::new_unbounded(1)
479    }
480
481    #[inline(always)]
482    pub const fn zero_or_more() -> Self {
483        Self::new_unbounded(0)
484    }
485
486    // --------------------------------------------------------------------------------------------
487    // Fields
488    // --------------------------------------------------------------------------------------------
489
490    #[inline(always)]
491    pub const fn min_occurs(&self) -> u32 {
492        self.min
493    }
494
495    #[inline(always)]
496    pub fn set_min_occurs(&mut self, min: u32) {
497        if let Some(max) = self.max {
498            assert!(min <= max);
499        }
500        self.min = min;
501    }
502
503    // --------------------------------------------------------------------------------------------
504
505    #[inline(always)]
506    pub const fn max_occurs(&self) -> Option<u32> {
507        self.max
508    }
509
510    #[inline(always)]
511    pub fn set_max_occurs(&mut self, max: u32) {
512        assert!(max > 0 && max >= self.min);
513        self.max = Some(max);
514    }
515
516    #[inline(always)]
517    pub fn unset_max_occurs(&mut self) {
518        self.max = None;
519    }
520
521    // --------------------------------------------------------------------------------------------
522    // Helpers
523    // --------------------------------------------------------------------------------------------
524
525    #[inline(always)]
526    pub const fn is_optional(&self) -> bool {
527        self.min_occurs() == 0
528    }
529
530    #[inline(always)]
531    pub const fn is_required(&self) -> bool {
532        !self.is_optional()
533    }
534
535    #[inline(always)]
536    pub fn is_range(&self) -> bool {
537        self.max.map(|i| i != self.min).unwrap_or(true)
538    }
539
540    #[inline(always)]
541    pub const fn is_unbounded(&self) -> bool {
542        self.max_occurs().is_none()
543    }
544
545    #[inline(always)]
546    pub fn is_exactly(&self, value: u32) -> bool {
547        self.min_occurs() == value && self.max_occurs().map(|i| i == value).unwrap_or(false)
548    }
549
550    // --------------------------------------------------------------------------------------------
551
552    #[inline(always)]
553    pub fn to_uml_string(&self) -> String {
554        if self.is_range() {
555            format!(
556                "{}..{}",
557                self.min_occurs(),
558                self.max_occurs()
559                    .map(|i| i.to_string())
560                    .unwrap_or_else(|| "*".to_string())
561            )
562        } else {
563            self.min.to_string()
564        }
565    }
566}
567
568// ------------------------------------------------------------------------------------------------
569// Implementations ❱ Members ❱ Ordering
570// ------------------------------------------------------------------------------------------------
571
572impl Default for Ordering {
573    fn default() -> Self {
574        Self::Unordered
575    }
576}
577
578impl FromStr for Ordering {
579    type Err = Error;
580
581    fn from_str(s: &str) -> Result<Self, Self::Err> {
582        match s {
583            KW_ORDERING_ORDERED => Ok(Self::Ordered),
584            KW_ORDERING_UNORDERED => Ok(Self::Unordered),
585            _ => panic!(),
586        }
587    }
588}
589
590impl Display for Ordering {
591    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
592        write!(
593            f,
594            "{}",
595            match self {
596                Self::Ordered => KW_ORDERING_ORDERED,
597                Self::Unordered => KW_ORDERING_UNORDERED,
598            }
599        )
600    }
601}
602
603// ------------------------------------------------------------------------------------------------
604// Implementations ❱ Members ❱ Uniqueness
605// ------------------------------------------------------------------------------------------------
606
607impl Default for Uniqueness {
608    fn default() -> Self {
609        Self::Nonunique
610    }
611}
612
613impl FromStr for Uniqueness {
614    type Err = Error;
615
616    fn from_str(s: &str) -> Result<Self, Self::Err> {
617        match s {
618            KW_UNIQUENESS_UNIQUE => Ok(Self::Unique),
619            KW_UNIQUENESS_NONUNIQUE => Ok(Self::Nonunique),
620            _ => panic!(),
621        }
622    }
623}
624
625impl Display for Uniqueness {
626    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
627        write!(
628            f,
629            "{}",
630            match self {
631                Self::Unique => KW_UNIQUENESS_UNIQUE,
632                Self::Nonunique => KW_UNIQUENESS_NONUNIQUE,
633            }
634        )
635    }
636}