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