xsd_parser/schema/
occurs.rs1use std::cmp::Ordering;
2use std::num::ParseIntError;
3use std::ops::AddAssign;
4use std::ops::{Add, Mul, MulAssign};
5use std::str::FromStr;
6
7use serde::{de::Error as DeError, Deserialize, Serialize};
8
9pub type MinOccurs = usize;
11
12#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)]
14pub enum MaxOccurs {
15 Unbounded,
17
18 Bounded(usize),
20}
21
22impl MaxOccurs {
23 #[inline]
25 #[must_use]
26 pub fn is_bounded(&self) -> bool {
27 matches!(self, Self::Bounded(_))
28 }
29}
30
31impl Add for MaxOccurs {
32 type Output = Self;
33
34 fn add(self, rhs: Self) -> Self::Output {
35 match (self, rhs) {
36 (Self::Bounded(a), Self::Bounded(b)) => Self::Bounded(a + b),
37 (_, _) => Self::Unbounded,
38 }
39 }
40}
41
42impl AddAssign for MaxOccurs {
43 fn add_assign(&mut self, rhs: Self) {
44 match (&mut *self, rhs) {
45 (Self::Bounded(a), Self::Bounded(b)) => *a += b,
46 (_, _) => *self = Self::Unbounded,
47 }
48 }
49}
50
51impl Mul for MaxOccurs {
52 type Output = Self;
53
54 fn mul(self, rhs: Self) -> Self::Output {
55 match (self, rhs) {
56 (Self::Bounded(a), Self::Bounded(b)) => Self::Bounded(a * b),
57 (_, _) => Self::Unbounded,
58 }
59 }
60}
61
62impl MulAssign for MaxOccurs {
63 fn mul_assign(&mut self, rhs: Self) {
64 match (&mut *self, rhs) {
65 (Self::Bounded(a), Self::Bounded(b)) => *a *= b,
66 (_, _) => *self = Self::Unbounded,
67 }
68 }
69}
70
71impl Ord for MaxOccurs {
72 fn cmp(&self, other: &Self) -> Ordering {
73 match (self, other) {
74 (Self::Bounded(a), Self::Bounded(b)) => a.cmp(b),
75 (Self::Unbounded, Self::Unbounded) => Ordering::Equal,
76 (Self::Bounded(_), Self::Unbounded) => Ordering::Less,
77 (Self::Unbounded, Self::Bounded(_)) => Ordering::Greater,
78 }
79 }
80}
81
82impl PartialOrd for MaxOccurs {
83 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
84 Some(Ord::cmp(self, other))
85 }
86}
87
88impl Default for MaxOccurs {
89 fn default() -> Self {
90 Self::Bounded(1)
91 }
92}
93
94impl FromStr for MaxOccurs {
95 type Err = ParseIntError;
96
97 fn from_str(s: &str) -> Result<Self, Self::Err> {
98 if s == "unbounded" {
99 Ok(Self::Unbounded)
100 } else {
101 Ok(Self::Bounded(usize::from_str(s)?))
102 }
103 }
104}
105
106impl Serialize for MaxOccurs {
107 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
108 where
109 S: serde::Serializer,
110 {
111 match self {
112 Self::Unbounded => serializer.serialize_str("unbounded"),
113 Self::Bounded(x) => serializer.serialize_str(&format!("{x}")),
114 }
115 }
116}
117
118impl<'de> Deserialize<'de> for MaxOccurs {
119 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
120 where
121 D: serde::Deserializer<'de>,
122 {
123 let s = String::deserialize(deserializer)?;
124 match s.as_str() {
125 "unbounded" => Ok(Self::Unbounded),
126 s => {
127 Ok(Self::Bounded(s.parse().map_err(|_| {
128 DeError::custom("MaxOccurs. Invalid value!")
129 })?))
130 }
131 }
132 }
133}