xsd_types/value/decimal/integer/
non_positive_integer.rs1use std::{
2 borrow::Borrow,
3 fmt,
4 ops::{Add, Div, Mul, Sub},
5 str::FromStr,
6};
7
8use num_bigint::{BigInt, TryFromBigIntError};
9use num_traits::{Signed, Zero};
10
11use crate::{
12 impl_integer_arithmetic,
13 lexical::{self, LexicalFormOf},
14 Datatype, Integer, NonPositiveIntegerDatatype, ParseXsd, XsdValue,
15};
16
17use super::Sign;
18
19#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
20pub struct NonPositiveInteger(BigInt);
21
22impl NonPositiveInteger {
23 pub unsafe fn new_unchecked(n: BigInt) -> Self {
29 Self(n)
30 }
31
32 pub fn from_bytes_be(bytes: &[u8]) -> Self {
35 Self(BigInt::from_bytes_be(Sign::Minus, bytes))
36 }
37
38 pub fn from_bytes_le(bytes: &[u8]) -> Self {
41 Self(BigInt::from_bytes_le(Sign::Minus, bytes))
42 }
43
44 pub unsafe fn from_signed_bytes_be_unchecked(bytes: &[u8]) -> Self {
51 Self(BigInt::from_signed_bytes_be(bytes))
52 }
53
54 pub unsafe fn from_signed_bytes_le_unchecked(bytes: &[u8]) -> Self {
61 Self(BigInt::from_signed_bytes_le(bytes))
62 }
63
64 pub fn from_signed_bytes_be(bytes: &[u8]) -> Result<Self, IntegerIsPositive> {
65 Integer::from_signed_bytes_be(bytes).try_into()
66 }
67
68 pub fn from_signed_bytes_le(bytes: &[u8]) -> Result<Self, IntegerIsPositive> {
69 Integer::from_signed_bytes_le(bytes).try_into()
70 }
71
72 #[inline(always)]
73 pub fn into_big_int(self) -> BigInt {
74 self.0
75 }
76
77 #[inline(always)]
78 pub fn zero() -> Self {
79 Self(BigInt::zero())
80 }
81
82 #[inline(always)]
83 pub fn is_zero(&self) -> bool {
84 self.0.is_zero()
85 }
86
87 #[inline(always)]
88 fn non_positive_integer_type(&self) -> NonPositiveIntegerDatatype {
89 if self.0 > BigInt::zero() {
90 NonPositiveIntegerDatatype::NegativeInteger
91 } else {
92 NonPositiveIntegerDatatype::NonPositiveInteger
93 }
94 }
95
96 #[inline(always)]
98 pub fn lexical_representation(&self) -> lexical::NonPositiveIntegerBuf {
99 unsafe {
100 lexical::NonPositiveIntegerBuf::new_unchecked(format!("{}", self))
103 }
104 }
105
106 pub fn to_bytes_be(&self) -> (Sign, Vec<u8>) {
107 self.0.to_bytes_be()
108 }
109
110 pub fn to_bytes_le(&self) -> (Sign, Vec<u8>) {
111 self.0.to_bytes_le()
112 }
113
114 pub fn to_signed_bytes_be(&self) -> Vec<u8> {
115 self.0.to_signed_bytes_be()
116 }
117
118 pub fn to_signed_bytes_le(&self) -> Vec<u8> {
119 self.0.to_signed_bytes_le()
120 }
121}
122
123impl XsdValue for NonPositiveInteger {
124 #[inline(always)]
125 fn datatype(&self) -> Datatype {
126 self.non_positive_integer_type().into()
127 }
128}
129
130impl ParseXsd for NonPositiveInteger {
131 type LexicalForm = lexical::NonPositiveInteger;
132}
133
134impl LexicalFormOf<NonPositiveInteger> for lexical::NonPositiveInteger {
135 type ValueError = std::convert::Infallible;
136
137 fn try_as_value(&self) -> Result<NonPositiveInteger, Self::ValueError> {
138 Ok(self.value())
139 }
140}
141
142impl From<NonPositiveInteger> for BigInt {
143 fn from(value: NonPositiveInteger) -> Self {
144 value.0
145 }
146}
147
148impl<'a> From<&'a lexical::NonPositiveInteger> for NonPositiveInteger {
149 #[inline(always)]
150 fn from(value: &'a lexical::NonPositiveInteger) -> Self {
151 Self(value.as_str().parse().unwrap())
152 }
153}
154
155impl From<lexical::NonPositiveIntegerBuf> for NonPositiveInteger {
156 #[inline(always)]
157 fn from(value: lexical::NonPositiveIntegerBuf) -> Self {
158 value.as_non_positive_integer().into()
159 }
160}
161
162impl FromStr for NonPositiveInteger {
163 type Err = lexical::InvalidNonPositiveInteger;
164
165 #[inline(always)]
166 fn from_str(s: &str) -> Result<Self, Self::Err> {
167 let l = lexical::NonPositiveInteger::new(s)?;
168 Ok(l.into())
169 }
170}
171
172impl fmt::Display for NonPositiveInteger {
173 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
174 self.0.fmt(f)
175 }
176}
177
178impl AsRef<BigInt> for NonPositiveInteger {
179 #[inline(always)]
180 fn as_ref(&self) -> &BigInt {
181 &self.0
182 }
183}
184
185impl Borrow<BigInt> for NonPositiveInteger {
186 #[inline(always)]
187 fn borrow(&self) -> &BigInt {
188 &self.0
189 }
190}
191
192impl_integer_arithmetic!(
193 for NonPositiveInteger where r ( !r.is_positive() ) {
194 Integer [.0],
195 NonPositiveInteger [.0],
196 NegativeInteger [.0],
197 super::NonNegativeInteger [.into_big_int()],
198 super::PositiveInteger [.into_big_int()],
199 i8,
200 i16,
201 i32,
202 i64,
203 isize,
204 u8,
205 u16,
206 u32,
207 u64,
208 usize
209 }
210);
211
212#[derive(Debug, thiserror::Error)]
213#[error("integer out of supported bounds: {0}")]
214pub struct NonPositiveIntegerOutOfTargetBounds(pub NonPositiveInteger);
215
216macro_rules! try_into {
217 { $( $ty:ty ),* } => {
218 $(
219 impl TryFrom<NonPositiveInteger> for $ty {
220 type Error = NonPositiveIntegerOutOfTargetBounds;
221
222 fn try_from(value: NonPositiveInteger) -> Result<Self, Self::Error> {
223 value.0.try_into().map_err(|e: TryFromBigIntError<BigInt>| NonPositiveIntegerOutOfTargetBounds(NonPositiveInteger(e.into_original())))
224 }
225 }
226 )*
227 };
228}
229
230try_into!(u8, u16, u32, u64, usize, i8, i16, i32, i64, isize);
231
232#[derive(Debug, thiserror::Error)]
233#[error("integer {0} is negative")]
234pub struct IntegerIsPositive(Integer);
235
236impl TryFrom<Integer> for NonPositiveInteger {
237 type Error = IntegerIsPositive;
238
239 fn try_from(value: Integer) -> Result<Self, Self::Error> {
240 if value.is_positive() {
241 Err(IntegerIsPositive(value))
242 } else {
243 Ok(Self(value.into()))
244 }
245 }
246}
247
248#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
249pub struct NegativeInteger(BigInt);
250
251impl NegativeInteger {
252 pub unsafe fn new_unchecked(n: BigInt) -> Self {
258 Self(n)
259 }
260
261 pub unsafe fn from_bytes_be_unchecked(bytes: &[u8]) -> Self {
268 Self(BigInt::from_bytes_be(Sign::Minus, bytes))
269 }
270
271 pub unsafe fn from_bytes_le_unchecked(bytes: &[u8]) -> Self {
278 Self(BigInt::from_bytes_le(Sign::Minus, bytes))
279 }
280
281 pub unsafe fn from_signed_bytes_be_unchecked(bytes: &[u8]) -> Self {
288 Self(BigInt::from_signed_bytes_be(bytes))
289 }
290
291 pub unsafe fn from_signed_bytes_le_unchecked(bytes: &[u8]) -> Self {
298 Self(BigInt::from_signed_bytes_le(bytes))
299 }
300
301 pub fn into_big_int(self) -> BigInt {
302 self.0
303 }
304
305 pub fn is_minus_one(&self) -> bool {
306 matches!(i8::try_from(&self.0), Ok(-1))
307 }
308
309 pub fn to_bytes_be(&self) -> (Sign, Vec<u8>) {
310 self.0.to_bytes_be()
311 }
312
313 pub fn to_bytes_le(&self) -> (Sign, Vec<u8>) {
314 self.0.to_bytes_le()
315 }
316
317 pub fn to_signed_bytes_be(&self) -> Vec<u8> {
318 self.0.to_signed_bytes_be()
319 }
320
321 pub fn to_signed_bytes_le(&self) -> Vec<u8> {
322 self.0.to_signed_bytes_le()
323 }
324}
325
326impl XsdValue for NegativeInteger {
327 fn datatype(&self) -> Datatype {
328 NonPositiveIntegerDatatype::NegativeInteger.into()
329 }
330}
331
332impl ParseXsd for NegativeInteger {
333 type LexicalForm = lexical::NegativeInteger;
334}
335
336impl LexicalFormOf<NegativeInteger> for lexical::NegativeInteger {
337 type ValueError = std::convert::Infallible;
338
339 fn try_as_value(&self) -> Result<NegativeInteger, Self::ValueError> {
340 Ok(self.value())
341 }
342}
343
344impl fmt::Display for NegativeInteger {
345 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
346 self.0.fmt(f)
347 }
348}
349
350impl From<NegativeInteger> for BigInt {
351 fn from(value: NegativeInteger) -> Self {
352 value.into_big_int()
353 }
354}
355
356impl_integer_arithmetic!(
357 for NegativeInteger where r ( r.is_negative() ) {
358 Integer [.0],
359 NonPositiveInteger [.0],
360 NegativeInteger [.0],
361 super::NonNegativeInteger [.into_big_int()],
362 super::PositiveInteger [.into_big_int()],
363 i8,
364 i16,
365 i32,
366 i64,
367 isize,
368 u8,
369 u16,
370 u32,
371 u64,
372 usize
373 }
374);