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