1#[cfg(test)]
2use internal_macros::EnumDebug;
3use std::error::Error;
4
5use super::{
6 error::{GrammarError, GrammarErrorType},
7 information_object::{InformationObjectFields, ObjectSet},
8 ASN1Type, ASN1Value, IntegerType,
9};
10
11#[derive(Debug, PartialEq)]
12pub struct OptionalMarker();
13
14impl From<&str> for OptionalMarker {
15 fn from(_: &str) -> Self {
16 OptionalMarker()
17 }
18}
19
20#[derive(Debug)]
21pub struct RangeSeperator();
22
23#[derive(Debug, Clone, PartialEq)]
24pub struct ExtensionMarker();
25
26#[cfg_attr(test, derive(EnumDebug))]
27#[cfg_attr(not(test), derive(Debug))]
28#[derive(Clone, PartialEq)]
29pub enum Constraint {
30 SubtypeConstraint(ElementSet),
31 TableConstraint(TableConstraint),
32 Parameter(Vec<Parameter>),
33 ContentConstraint(ContentConstraint),
34}
35
36impl Constraint {
37 pub fn integer_constraints(&self) -> IntegerType {
40 let (mut min, mut max, mut is_extensible) = (i128::MAX, i128::MIN, false);
41 if let Ok((cmin, cmax, extensible)) = self.unpack_as_value_range() {
42 is_extensible = is_extensible || extensible;
43 if let Some(ASN1Value::Integer(i)) = cmin {
44 min = (*i).min(min);
45 };
46 if let Some(ASN1Value::Integer(i)) = cmax {
47 max = (*i).max(max);
48 };
49 } else if let Ok((val, extensible)) = self.unpack_as_strict_value() {
50 is_extensible = is_extensible || extensible;
51 if let ASN1Value::Integer(i) = val {
52 min = (*i).min(min);
53 max = (*i).max(max);
54 };
55 };
56 if min > max || is_extensible {
57 IntegerType::Unbounded
58 } else if min >= 0 {
59 match max {
60 r if r <= u8::MAX.into() => IntegerType::Uint8,
61 r if r <= u16::MAX.into() => IntegerType::Uint16,
62 r if r <= u32::MAX.into() => IntegerType::Uint32,
63 r if r <= u64::MAX.into() => IntegerType::Uint64,
64 _ => IntegerType::Unbounded,
65 }
66 } else {
67 match (min, max) {
68 (mi, ma) if mi >= i8::MIN.into() && ma <= i8::MAX.into() => IntegerType::Int8,
69 (mi, ma) if mi >= i16::MIN.into() && ma <= i16::MAX.into() => IntegerType::Int16,
70 (mi, ma) if mi >= i32::MIN.into() && ma <= i32::MAX.into() => IntegerType::Int32,
71 (mi, ma) if mi >= i64::MIN.into() && ma <= i64::MAX.into() => IntegerType::Int64,
72 _ => IntegerType::Unbounded,
73 }
74 }
75 }
76
77 pub fn unpack_as_value_range(
78 &self,
79 ) -> Result<(&Option<ASN1Value>, &Option<ASN1Value>, bool), GrammarError> {
80 if let Constraint::SubtypeConstraint(set) = self {
81 if let ElementOrSetOperation::Element(SubtypeElement::ValueRange {
82 min,
83 max,
84 extensible,
85 }) = &set.set
86 {
87 return Ok((min, max, *extensible));
88 }
89 }
90 Err(GrammarError::new(
91 &format!(
92 "Failed to unpack constraint as value range. Constraint: {:?}",
93 self
94 ),
95 GrammarErrorType::UnpackingError,
96 ))
97 }
98
99 pub fn unpack_as_strict_value(&self) -> Result<(&ASN1Value, bool), GrammarError> {
100 if let Constraint::SubtypeConstraint(set) = self {
101 if let ElementOrSetOperation::Element(SubtypeElement::SingleValue {
102 value,
103 extensible,
104 }) = &set.set
105 {
106 return Ok((value, *extensible));
107 }
108 }
109 Err(GrammarError::new(
110 &format!(
111 "Failed to unpack constraint as strict value. Constraint: {:?}",
112 self
113 ),
114 GrammarErrorType::UnpackingError,
115 ))
116 }
117}
118
119#[cfg_attr(test, derive(EnumDebug))]
120#[cfg_attr(not(test), derive(Debug))]
121#[derive(Clone, PartialEq)]
122pub enum ContentConstraint {
123 Containing(ASN1Type),
124 EncodedBy(ASN1Value),
125 ContainingEncodedBy {
126 containing: ASN1Type,
127 encoded_by: ASN1Value,
128 },
129}
130
131impl From<ASN1Type> for ContentConstraint {
132 fn from(value: ASN1Type) -> Self {
133 ContentConstraint::Containing(value)
134 }
135}
136
137impl From<ASN1Value> for ContentConstraint {
138 fn from(value: ASN1Value) -> Self {
139 ContentConstraint::EncodedBy(value)
140 }
141}
142
143impl From<(ASN1Type, ASN1Value)> for ContentConstraint {
144 fn from(value: (ASN1Type, ASN1Value)) -> Self {
145 ContentConstraint::ContainingEncodedBy {
146 containing: value.0,
147 encoded_by: value.1,
148 }
149 }
150}
151
152#[cfg_attr(test, derive(EnumDebug))]
153#[cfg_attr(not(test), derive(Debug))]
154#[derive(Clone, PartialEq)]
155pub enum Parameter {
156 ValueParameter(ASN1Value),
157 TypeParameter(ASN1Type),
158 InformationObjectParameter(InformationObjectFields),
159 ObjectSetParameter(ObjectSet),
160}
161
162#[cfg_attr(test, derive(EnumDebug))]
163#[cfg_attr(not(test), derive(Debug))]
164#[derive(Clone, PartialEq)]
165pub enum SetOperator {
166 Intersection,
167 Union,
168 Except,
169}
170
171#[derive(Debug, Clone, PartialEq)]
172pub struct CompositeConstraint {
173 pub base_constraint: Box<Constraint>,
174 pub operation: Vec<(SetOperator, Box<Constraint>)>,
175 pub extensible: bool,
176}
177
178impl
179 From<(
180 Constraint,
181 Vec<(SetOperator, Constraint)>,
182 Option<ExtensionMarker>,
183 )> for CompositeConstraint
184{
185 fn from(
186 value: (
187 Constraint,
188 Vec<(SetOperator, Constraint)>,
189 Option<ExtensionMarker>,
190 ),
191 ) -> Self {
192 Self {
193 base_constraint: Box::new(value.0),
194 operation: value
195 .1
196 .into_iter()
197 .map(|(op, c)| (op, Box::new(c)))
198 .collect(),
199 extensible: value.2.is_some(),
200 }
201 }
202}
203
204#[cfg_attr(test, derive(EnumDebug))]
205#[cfg_attr(not(test), derive(Debug))]
206#[derive(Clone, PartialEq)]
207pub enum ComponentPresence {
208 Absent,
209 Present,
210 Unspecified,
211}
212
213#[derive(Debug, Clone, PartialEq)]
216pub struct InnerTypeConstraint {
217 pub is_partial: bool,
218 pub constraints: Vec<ConstrainedComponent>,
219}
220
221#[derive(Debug, Clone, PartialEq)]
224pub struct ConstrainedComponent {
225 pub identifier: String,
226 pub constraints: Vec<Constraint>,
227 pub presence: ComponentPresence,
228}
229
230#[derive(Debug, Clone, PartialEq)]
233pub struct ValueConstraint {
234 pub min_value: Option<ASN1Value>,
235 pub max_value: Option<ASN1Value>,
236 pub extensible: bool,
237}
238
239impl From<ASN1Value> for ValueConstraint {
240 fn from(value: ASN1Value) -> Self {
241 Self {
242 min_value: Some(value.clone()),
243 max_value: Some(value),
244 extensible: false,
245 }
246 }
247}
248
249impl From<(ASN1Value, RangeSeperator, ASN1Value)> for ValueConstraint {
250 fn from(value: (ASN1Value, RangeSeperator, ASN1Value)) -> Self {
251 Self {
252 min_value: Some(value.0),
253 max_value: Some(value.2),
254 extensible: false,
255 }
256 }
257}
258
259impl From<(ASN1Value, ExtensionMarker)> for ValueConstraint {
260 fn from(value: (ASN1Value, ExtensionMarker)) -> Self {
261 Self {
262 min_value: Some(value.0.clone()),
263 max_value: Some(value.0),
264 extensible: true,
265 }
266 }
267}
268
269impl From<(ASN1Value, RangeSeperator, ASN1Value, ExtensionMarker)> for ValueConstraint {
270 fn from(value: (ASN1Value, RangeSeperator, ASN1Value, ExtensionMarker)) -> Self {
271 Self {
272 min_value: Some(value.0),
273 max_value: Some(value.2),
274 extensible: true,
275 }
276 }
277}
278
279#[derive(Debug, Clone, PartialEq)]
283pub struct TableConstraint {
284 pub object_set: ObjectSet,
285 pub linked_fields: Vec<RelationalConstraint>,
286}
287
288impl From<(ObjectSet, Option<Vec<RelationalConstraint>>)> for TableConstraint {
289 fn from(value: (ObjectSet, Option<Vec<RelationalConstraint>>)) -> Self {
290 Self {
291 object_set: value.0,
292 linked_fields: value.1.unwrap_or_default(),
293 }
294 }
295}
296
297#[derive(Debug, Clone, PartialEq)]
300pub struct RelationalConstraint {
301 pub field_name: String,
302 pub level: usize,
305}
306
307impl From<(usize, &str)> for RelationalConstraint {
308 fn from(value: (usize, &str)) -> Self {
309 Self {
310 field_name: value.1.into(),
311 level: value.0,
312 }
313 }
314}
315
316#[derive(Debug, Clone, PartialEq)]
319pub struct PatternConstraint {
320 pub pattern: String,
321}
322
323impl From<&str> for PatternConstraint {
324 fn from(value: &str) -> Self {
325 Self {
326 pattern: value.into(),
327 }
328 }
329}
330
331#[derive(Debug, Clone, PartialEq)]
334pub struct UserDefinedConstraint {
335 pub definition: String,
336}
337
338impl From<&str> for UserDefinedConstraint {
339 fn from(value: &str) -> Self {
340 Self {
341 definition: value.into(),
342 }
343 }
344}
345
346#[derive(Debug, Clone, PartialEq)]
349pub struct PropertySettings {
350 pub property_settings_list: Vec<PropertyAndSettingsPair>,
351}
352
353impl From<Vec<&str>> for PropertySettings {
354 fn from(_value: Vec<&str>) -> Self {
355 todo!()
356 }
357}
358
359#[cfg_attr(test, derive(EnumDebug))]
360#[cfg_attr(not(test), derive(Debug))]
361#[derive(Clone, PartialEq)]
362pub enum PropertyAndSettingsPair {
363 Basic(BasicSettings),
364 Date(DateSettings),
365 Year(YearSettings),
366 Time(TimeSettings),
367 LocalOrUtc(LocalOrUtcSettings),
368 IntervalType(IntervalTypeSettings),
369 StartEndPoint(StartEndPointSettings),
370 Recurrence(RecurrenceSettings),
371 Midnight(MidnightSettings),
372}
373
374impl TryFrom<(&str, &str)> for PropertyAndSettingsPair {
375 fn try_from(value: (&str, &str)) -> Result<PropertyAndSettingsPair, Box<dyn Error>> {
376 match value.0 {
377 BasicSettings::NAME => BasicSettings::from_str(value.1).map(Self::Basic),
378 DateSettings::NAME => DateSettings::from_str(value.1).map(Self::Date),
379 YearSettings::NAME => YearSettings::from_str(value.1).map(Self::Year),
380 TimeSettings::NAME => TimeSettings::from_str(value.1).map(Self::Time),
381 LocalOrUtcSettings::NAME => LocalOrUtcSettings::from_str(value.1).map(Self::LocalOrUtc),
382 IntervalTypeSettings::NAME => {
383 IntervalTypeSettings::from_str(value.1).map(Self::IntervalType)
384 }
385 StartEndPointSettings::NAME => {
386 StartEndPointSettings::from_str(value.1).map(Self::StartEndPoint)
387 }
388 RecurrenceSettings::NAME => RecurrenceSettings::from_str(value.1).map(Self::Recurrence),
389 MidnightSettings::NAME => MidnightSettings::from_str(value.1).map(Self::Midnight),
390 _ => Err("Unknown Settings value.".into()),
391 }
392 }
393
394 type Error = Box<dyn Error>;
395}
396
397pub trait PropertySetting {
398 const NAME: &'static str;
399
400 fn setting_name(&self) -> String;
401
402 fn from_str(value: &str) -> Result<Self, Box<dyn Error>>
403 where
404 Self: Sized;
405}
406
407#[cfg_attr(test, derive(EnumDebug))]
408#[cfg_attr(not(test), derive(Debug))]
409#[derive(Clone, PartialEq)]
410pub enum BasicSettings {
411 Date,
412 Time,
413 DateTime,
414 Interval,
415 RecInterval,
416}
417
418impl PropertySetting for BasicSettings {
419 const NAME: &'static str = "Basic";
420
421 fn setting_name(&self) -> String {
422 match self {
423 BasicSettings::Date => "Date".into(),
424 BasicSettings::Time => "Time".into(),
425 BasicSettings::DateTime => "Date-Time".into(),
426 BasicSettings::Interval => "Interval".into(),
427 BasicSettings::RecInterval => "Rec-Interval".into(),
428 }
429 }
430
431 fn from_str(value: &str) -> Result<Self, Box<dyn Error>> {
432 match value {
433 "Date" => Ok(BasicSettings::Date),
434 "Time" => Ok(BasicSettings::Time),
435 "Date-Time" => Ok(BasicSettings::DateTime),
436 "Interval" => Ok(BasicSettings::Interval),
437 "Rec-Interval" => Ok(BasicSettings::RecInterval),
438 _ => Err("Unknown Settings value.".into()),
439 }
440 }
441}
442
443impl PropertySetting for DateSettings {
444 const NAME: &'static str = "Date";
445
446 fn setting_name(&self) -> String {
447 match self {
448 DateSettings::Century => "C".into(),
449 DateSettings::Year => "Y".into(),
450 DateSettings::YearMonth => "YM".into(),
451 DateSettings::YearMonthDay => "YMD".into(),
452 DateSettings::YearDay => "YD".into(),
453 DateSettings::YearWeek => "YW".into(),
454 DateSettings::YearWeekDay => "YWD".into(),
455 }
456 }
457
458 fn from_str(value: &str) -> Result<Self, Box<dyn Error>> {
459 match value {
460 "C" => Ok(DateSettings::Century),
461 "Y" => Ok(DateSettings::Year),
462 "YM" => Ok(DateSettings::YearMonth),
463 "YMD" => Ok(DateSettings::YearMonthDay),
464 "YD" => Ok(DateSettings::YearDay),
465 "YW" => Ok(DateSettings::YearWeek),
466 "YWD" => Ok(DateSettings::YearWeekDay),
467 _ => Err("Unknown Settings value.".into()),
468 }
469 }
470}
471
472#[cfg_attr(test, derive(EnumDebug))]
473#[cfg_attr(not(test), derive(Debug))]
474#[derive(Clone, PartialEq)]
475pub enum DateSettings {
476 Century,
477 Year,
478 YearMonth,
479 YearMonthDay,
480 YearDay,
481 YearWeek,
482 YearWeekDay,
483}
484
485impl PropertySetting for YearSettings {
486 const NAME: &'static str = "Year";
487
488 fn setting_name(&self) -> String {
489 match self {
490 YearSettings::Basic => "Basic".into(),
491 YearSettings::Proleptic => "Proleptic".into(),
492 YearSettings::Negative => "Negative".into(),
493 YearSettings::Large(i) => format!("L{i}"),
494 }
495 }
496
497 fn from_str(value: &str) -> Result<Self, Box<dyn Error>> {
498 match value {
499 "Basic" => Ok(YearSettings::Basic),
500 "Proleptic" => Ok(YearSettings::Proleptic),
501 "Negative" => Ok(YearSettings::Negative),
502 s if s.starts_with('L') => Ok(s[1..].parse().map(YearSettings::Large)?),
503 _ => Err("Unknown Settings value.".into()),
504 }
505 }
506}
507
508#[cfg_attr(test, derive(EnumDebug))]
509#[cfg_attr(not(test), derive(Debug))]
510#[derive(Clone, PartialEq)]
511pub enum YearSettings {
512 Basic,
513 Proleptic,
514 Negative,
515 Large(usize),
516}
517
518impl PropertySetting for TimeSettings {
519 const NAME: &'static str = "Time";
520
521 fn setting_name(&self) -> String {
522 match self {
523 TimeSettings::Hour => "H".into(),
524 TimeSettings::HourMinute => "HM".into(),
525 TimeSettings::HourMinuteSecond => "HMS".into(),
526 TimeSettings::HourDecimalFraction(i) => format!("HF{i}"),
527 TimeSettings::HourMinuteFraction(i) => format!("HMF{i}"),
528 TimeSettings::HourMinuteSecondFraction(i) => format!("HMSF{i}"),
529 }
530 }
531
532 fn from_str(value: &str) -> Result<Self, Box<dyn Error>> {
533 match value {
534 "H" => Ok(TimeSettings::Hour),
535 "HM" => Ok(TimeSettings::HourMinute),
536 "HMS" => Ok(TimeSettings::HourMinuteSecond),
537 s if s.starts_with("HF") => {
538 Ok(s[2..].parse().map(TimeSettings::HourDecimalFraction)?)
539 }
540 s if s.starts_with("HMF") => {
541 Ok(s[3..].parse().map(TimeSettings::HourMinuteFraction)?)
542 }
543 s if s.starts_with("HMSF") => {
544 Ok(s[4..].parse().map(TimeSettings::HourMinuteSecondFraction)?)
545 }
546 _ => Err("Unknown Settings value.".into()),
547 }
548 }
549}
550
551#[cfg_attr(test, derive(EnumDebug))]
552#[cfg_attr(not(test), derive(Debug))]
553#[derive(Clone, PartialEq)]
554pub enum TimeSettings {
555 Hour,
556 HourMinute,
557 HourMinuteSecond,
558 HourDecimalFraction(usize),
559 HourMinuteFraction(usize),
560 HourMinuteSecondFraction(usize),
561}
562
563impl PropertySetting for LocalOrUtcSettings {
564 const NAME: &'static str = "Local-or-UTC";
565
566 fn setting_name(&self) -> String {
567 match self {
568 LocalOrUtcSettings::Local => "L".into(),
569 LocalOrUtcSettings::Utc => "Z".into(),
570 LocalOrUtcSettings::LocalAndDifference => "LD".into(),
571 }
572 }
573
574 fn from_str(value: &str) -> Result<Self, Box<dyn Error>> {
575 match value {
576 "L" => Ok(LocalOrUtcSettings::Local),
577 "Z" => Ok(LocalOrUtcSettings::Utc),
578 "LD" => Ok(LocalOrUtcSettings::LocalAndDifference),
579 _ => Err("Unknown Settings value.".into()),
580 }
581 }
582}
583
584#[cfg_attr(test, derive(EnumDebug))]
585#[cfg_attr(not(test), derive(Debug))]
586#[derive(Clone, PartialEq)]
587pub enum LocalOrUtcSettings {
588 Local,
589 Utc,
590 LocalAndDifference,
591}
592
593impl PropertySetting for IntervalTypeSettings {
594 const NAME: &'static str = "Interval-type";
595
596 fn setting_name(&self) -> String {
597 match self {
598 IntervalTypeSettings::StartAndEnd => "SE".into(),
599 IntervalTypeSettings::Duration => "D".into(),
600 IntervalTypeSettings::StartAndDuration => "SD".into(),
601 IntervalTypeSettings::DurationAndEnd => "DE".into(),
602 }
603 }
604
605 fn from_str(value: &str) -> Result<Self, Box<dyn Error>> {
606 match value {
607 "SE" => Ok(IntervalTypeSettings::StartAndEnd),
608 "D" => Ok(IntervalTypeSettings::Duration),
609 "SD" => Ok(IntervalTypeSettings::StartAndDuration),
610 "DE" => Ok(IntervalTypeSettings::DurationAndEnd),
611 _ => Err("Unknown Settings value.".into()),
612 }
613 }
614}
615
616#[cfg_attr(test, derive(EnumDebug))]
617#[cfg_attr(not(test), derive(Debug))]
618#[derive(Clone, PartialEq)]
619pub enum IntervalTypeSettings {
620 StartAndEnd,
621 Duration,
622 StartAndDuration,
623 DurationAndEnd,
624}
625
626impl PropertySetting for StartEndPointSettings {
627 const NAME: &'static str = "SE-point";
628
629 fn setting_name(&self) -> String {
630 match self {
631 StartEndPointSettings::Date => "Date".into(),
632 StartEndPointSettings::Time => "Time".into(),
633 StartEndPointSettings::DateTime => "Date-Time".into(),
634 }
635 }
636
637 fn from_str(value: &str) -> Result<Self, Box<dyn Error>> {
638 match value {
639 "Date" => Ok(StartEndPointSettings::Date),
640 "Time" => Ok(StartEndPointSettings::Time),
641 "Date-Time" => Ok(StartEndPointSettings::DateTime),
642 _ => Err("Unknown Settings value.".into()),
643 }
644 }
645}
646
647#[cfg_attr(test, derive(EnumDebug))]
648#[cfg_attr(not(test), derive(Debug))]
649#[derive(Clone, PartialEq)]
650pub enum StartEndPointSettings {
651 Date,
652 Time,
653 DateTime,
654}
655
656impl PropertySetting for RecurrenceSettings {
657 const NAME: &'static str = "Recurrence";
658
659 fn setting_name(&self) -> String {
660 match self {
661 RecurrenceSettings::Unlimited => "Unlimited".into(),
662 RecurrenceSettings::Recurrences(i) => format!("R{i}"),
663 }
664 }
665
666 fn from_str(value: &str) -> Result<Self, Box<dyn Error>> {
667 match value {
668 "Unlimited" => Ok(RecurrenceSettings::Unlimited),
669 s if s.starts_with('R') => Ok(s[1..].parse().map(RecurrenceSettings::Recurrences)?),
670 _ => Err("Unknown Settings value.".into()),
671 }
672 }
673}
674
675#[cfg_attr(test, derive(EnumDebug))]
676#[cfg_attr(not(test), derive(Debug))]
677#[derive(Clone, PartialEq)]
678pub enum RecurrenceSettings {
679 Unlimited,
680 Recurrences(usize),
681}
682
683impl PropertySetting for MidnightSettings {
684 const NAME: &'static str = "Midnight";
685
686 fn setting_name(&self) -> String {
687 match self {
688 MidnightSettings::StartOfDay => "Start".into(),
689 MidnightSettings::EndOfDay => "End".into(),
690 }
691 }
692
693 fn from_str(value: &str) -> Result<Self, Box<dyn Error>> {
694 match value {
695 "Start" => Ok(MidnightSettings::StartOfDay),
696 "End" => Ok(MidnightSettings::EndOfDay),
697 _ => Err("Unknown Settings value.".into()),
698 }
699 }
700}
701
702#[cfg_attr(test, derive(EnumDebug))]
703#[cfg_attr(not(test), derive(Debug))]
704#[derive(Clone, PartialEq)]
705pub enum MidnightSettings {
706 StartOfDay,
707 EndOfDay,
708}
709
710#[cfg_attr(test, derive(EnumDebug))]
711#[cfg_attr(not(test), derive(Debug))]
712#[derive(Clone, PartialEq)]
713pub enum SubtypeElement {
714 SingleValue {
715 value: ASN1Value,
716 extensible: bool,
717 },
718 ContainedSubtype {
719 subtype: ASN1Type,
720 extensible: bool,
721 },
722 ValueRange {
723 min: Option<ASN1Value>,
724 max: Option<ASN1Value>,
725 extensible: bool,
726 },
727 PermittedAlphabet(Box<ElementOrSetOperation>),
728 SizeConstraint(Box<ElementOrSetOperation>),
729 TypeConstraint(ASN1Type),
730 SingleTypeConstraint(Vec<Constraint>),
731 MultipleTypeConstraints(InnerTypeConstraint),
732 PatternConstraint(PatternConstraint),
733 UserDefinedConstraint(UserDefinedConstraint),
734 PropertySettings(PropertySettings), }
738
739impl From<(ASN1Value, Option<ExtensionMarker>)> for SubtypeElement {
740 fn from(value: (ASN1Value, Option<ExtensionMarker>)) -> Self {
741 Self::SingleValue {
742 value: value.0,
743 extensible: value.1.is_some(),
744 }
745 }
746}
747
748impl From<Constraint> for SubtypeElement {
749 fn from(value: Constraint) -> Self {
750 match value {
751 Constraint::SubtypeConstraint(set) => Self::SizeConstraint(Box::new(set.set)),
752 _ => unreachable!(),
753 }
754 }
755}
756
757impl
758 From<(
759 Option<ExtensionMarker>,
760 Vec<(&str, Option<Vec<Constraint>>, Option<ComponentPresence>)>,
761 )> for SubtypeElement
762{
763 fn from(
764 value: (
765 Option<ExtensionMarker>,
766 Vec<(&str, Option<Vec<Constraint>>, Option<ComponentPresence>)>,
767 ),
768 ) -> Self {
769 SubtypeElement::MultipleTypeConstraints(InnerTypeConstraint {
770 is_partial: value.0.is_some(),
771 constraints: value
772 .1
773 .into_iter()
774 .map(|(id, constraint, presence)| ConstrainedComponent {
775 identifier: String::from(id),
776 constraints: constraint.unwrap_or(vec![]),
777 presence: presence.unwrap_or(ComponentPresence::Unspecified),
778 })
779 .collect(),
780 })
781 }
782}
783
784#[derive(Debug, Clone, PartialEq)]
785pub struct ElementSet {
786 pub set: ElementOrSetOperation,
787 pub extensible: bool,
788}
789
790impl From<(ElementOrSetOperation, Option<ExtensionMarker>)> for ElementSet {
791 fn from(value: (ElementOrSetOperation, Option<ExtensionMarker>)) -> Self {
792 Self {
793 set: value.0,
794 extensible: value.1.is_some(),
795 }
796 }
797}
798
799#[cfg_attr(test, derive(EnumDebug))]
800#[cfg_attr(not(test), derive(Debug))]
801#[derive(Clone, PartialEq)]
802pub enum ElementOrSetOperation {
803 Element(SubtypeElement),
804 SetOperation(SetOperation),
805}
806
807#[derive(Debug, Clone, PartialEq)]
808pub struct SetOperation {
809 pub base: SubtypeElement, pub operator: SetOperator,
811 pub operant: Box<ElementOrSetOperation>,
812}
813
814impl From<(SubtypeElement, SetOperator, ElementOrSetOperation)> for SetOperation {
815 fn from(value: (SubtypeElement, SetOperator, ElementOrSetOperation)) -> Self {
816 Self {
817 base: value.0,
818 operator: value.1,
819 operant: Box::new(value.2),
820 }
821 }
822}