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
16pub trait HasCardinality {
21 fn target_cardinality(&self) -> &Cardinality;
22
23 fn set_target_cardinality(&mut self, target_cardinality: Cardinality);
24}
25
26#[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#[derive(Clone, Copy, Debug, PartialEq, Eq)]
65#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
66pub enum Ordering {
67 Ordered,
68 Unordered,
69}
70
71#[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
88impl 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 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 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 #[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 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 #[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 #[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 #[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
372impl 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 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 #[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 #[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 #[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 #[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
568impl 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
603impl 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}