1#![doc = include_str!("../README.md")]
2#![no_std]
3#![cfg(feature = "alloc")]
4extern crate alloc;
5
6#[derive(Debug, Clone, Copy)]
8pub struct MathError;
9
10impl core::fmt::Display for MathError {
11 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
12 write!(f, "MathError")
13 }
14}
15
16#[derive(Debug, Clone, PartialEq, Eq, Copy)]
17pub enum MathErrors {
18 InvalidInput,
19 Overflow,
20 Underflow,
21 DivisionByZero,
22}
23
24#[derive(Debug, Clone, Copy)]
25pub struct MathErrorsInvalidInput;
26
27impl core::fmt::Display for MathErrorsInvalidInput {
28 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
29 write!(f, "InvalidInput")
30 }
31}
32
33#[derive(Debug, Clone, Copy)]
34pub struct MathErrorsOverflow;
35
36impl core::fmt::Display for MathErrorsOverflow {
37 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
38 write!(f, "Overflow")
39 }
40}
41
42#[derive(Debug, Clone, Copy)]
43pub struct MathErrorsUnderflow;
44
45impl core::fmt::Display for MathErrorsUnderflow {
46 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
47 write!(f, "Underflow")
48 }
49}
50#[derive(Debug, Clone, Copy)]
51pub struct MathErrorsDivisionByZero;
52
53impl core::fmt::Display for MathErrorsDivisionByZero {
54 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
55 write!(f, "DivisionByZero")
56 }
57}
58
59impl From<MathErrorsInvalidInput> for MathError {
60 fn from(_: MathErrorsInvalidInput) -> Self {
61 MathError
62 }
63}
64
65impl From<MathErrorsInvalidInput> for MathErrors {
66 fn from(_: MathErrorsInvalidInput) -> Self {
67 MathErrors::InvalidInput
68 }
69}
70
71impl From<MathErrorsOverflow> for MathErrors {
72 fn from(_: MathErrorsOverflow) -> Self {
73 MathErrors::Overflow
74 }
75}
76
77impl From<MathErrorsUnderflow> for MathErrors {
78 fn from(_: MathErrorsUnderflow) -> Self {
79 MathErrors::Underflow
80 }
81}
82
83impl From<MathErrorsDivisionByZero> for MathErrors {
84 fn from(_: MathErrorsDivisionByZero) -> Self {
85 MathErrors::DivisionByZero
86 }
87}
88
89impl From<MathErrorsOverflow> for MathError {
90 fn from(_: MathErrorsOverflow) -> Self {
91 MathError
92 }
93}
94
95impl From<MathErrorsUnderflow> for MathError {
96 fn from(_: MathErrorsUnderflow) -> Self {
97 MathError
98 }
99}
100
101impl From<MathErrorsDivisionByZero> for MathError {
102 fn from(_: MathErrorsDivisionByZero) -> Self {
103 MathError
104 }
105}
106
107impl core::fmt::Display for MathErrors {
108 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
109 match self {
110 MathErrors::InvalidInput => write!(f, "InvalidInput"),
111 MathErrors::Overflow => write!(f, "Overflow"),
112 MathErrors::Underflow => write!(f, "Underflow"),
113 MathErrors::DivisionByZero => write!(f, "Division"),
114 }
115 }
116}
117
118impl Into<u8> for MathErrors {
119 fn into(self) -> u8 {
120 self.to_primitive()
121 }
122}
123
124impl MathErrors {
125 pub const fn is_invalid_input(&self) -> bool {
126 matches!(self, MathErrors::InvalidInput)
127 }
128
129 pub const fn is_overflow(&self) -> bool {
130 matches!(self, MathErrors::Overflow)
131 }
132
133 pub const fn is_underflow(&self) -> bool {
134 matches!(self, MathErrors::Underflow)
135 }
136
137 pub const fn is_division_by_zero(&self) -> bool {
138 matches!(self, MathErrors::DivisionByZero)
139 }
140
141 pub const fn to_primitive(&self) -> u8 {
142 match self {
143 MathErrors::InvalidInput => 0,
144 MathErrors::Overflow => 1,
145 MathErrors::Underflow => 2,
146 MathErrors::DivisionByZero => 3,
147 }
148 }
149
150 pub const fn try_from_primitive(value: u8) -> Option<Self> {
151 match value {
152 0 => Some(MathErrors::InvalidInput),
153 1 => Some(MathErrors::Overflow),
154 2 => Some(MathErrors::Underflow),
155 3 => Some(MathErrors::DivisionByZero),
156 _ => None,
157 }
158 }
159
160 pub const fn to_str(&self) -> &'static str {
161 match self {
162 MathErrors::InvalidInput => "InvalidInput",
163 MathErrors::Overflow => "Overflow",
164 MathErrors::Underflow => "Underflow",
165 MathErrors::DivisionByZero => "DivisionByZero",
166 }
167 }
168}
169
170impl TryFrom<u8> for MathErrors {
171 type Error = &'static str;
172
173 fn try_from(value: u8) -> Result<Self, Self::Error> {
174 Self::try_from_primitive(value).ok_or("Must be in range 0..=3")
175 }
176}
177
178impl From<MathErrors> for MathError {
179 fn from(_: MathErrors) -> Self {
180 MathError
181 }
182}
183
184impl core::str::FromStr for MathErrors {
185 type Err = &'static str;
186
187 fn from_str(s: &str) -> Result<Self, Self::Err> {
188 match s {
189 "InvalidInput" => Ok(MathErrors::InvalidInput),
190 "Overflow" => Ok(MathErrors::Overflow),
191 "Underflow" => Ok(MathErrors::Underflow),
192 "DivisionByZero" => Ok(MathErrors::DivisionByZero),
193 _ => Err("InvalidInput, Overlow, Underflow, or DivisionByZero"),
194 }
195 }
196}
197
198#[cfg(feature = "serde1")]
200mod serde1_impl {
201 use super::*;
202 use serde1::{de::Visitor, Deserialize, Serialize};
203
204 impl Serialize for MathErrors {
205 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
206 where
207 S: serde1::Serializer,
208 {
209 serializer.serialize_str(self.to_str())
210 }
211 }
212
213 impl<'de> Deserialize<'de> for MathErrors {
214 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
215 where
216 D: serde1::Deserializer<'de>,
217 {
218 use core::fmt;
219 struct SelfVisitor;
220 impl Visitor<'_> for SelfVisitor {
221 type Value = MathErrors;
222
223 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
224 write!(
226 formatter,
227 "InvalidInput, Overflow, Underflow, or DivisionByZero"
228 )
229 }
230
231 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
232 where
233 E: serde1::de::Error,
234 {
235 match v {
236 "InvalidInput" => Ok(MathErrors::InvalidInput),
237 "Overflow" => Ok(MathErrors::Overflow),
238 "Underflow" => Ok(MathErrors::Underflow),
239 "DivisionByZero" => Ok(MathErrors::DivisionByZero),
240 _ => Err(E::invalid_value(
241 serde1::de::Unexpected::Str(v),
242 &"InvalidInput, Overlow, Underflow, or DivisionByZero",
243 )),
244 }
245 }
246 }
247
248 deserializer.deserialize_str(SelfVisitor)
249 }
250 }
251
252 #[cfg(feature = "schemars1")]
253 mod schemars1_impl {
254 use super::*;
255 use schemars1::{json_schema, JsonSchema};
256
257 impl JsonSchema for MathErrors {
258 fn schema_name() -> alloc::borrow::Cow<'static, str> {
259 "MathErrors".into()
260 }
261
262 fn json_schema(_generator: &mut schemars1::SchemaGenerator) -> schemars1::Schema {
263 json_schema!(
264 {
265 "description": "Simple math error",
266 "type": ["string"],
267 "enum": [
268 "InvalidInput",
269 "Overflow",
270 "Underflow",
271 "DivisionByZero"
272 ],
273 "maxLength": 14,
274 "minLength": 8,
275 }
276 )
277 }
278 }
279 }
280}
281
282#[cfg(feature = "borsh1")]
283mod borsh1 {
284 use borsh1::{BorshDeserialize, BorshSerialize};
285
286 use crate::MathErrors;
287
288 impl BorshDeserialize for MathErrors {
289 fn deserialize_reader<R: borsh1::io::Read>(reader: &mut R) -> borsh1::io::Result<Self> {
290 let value = u8::deserialize_reader(reader)?;
291 Self::try_from_primitive(value).ok_or(borsh1::io::ErrorKind::InvalidData.into())
292 }
293 }
294
295 impl BorshSerialize for MathErrors {
296 fn serialize<W: borsh1::io::Write>(&self, writer: &mut W) -> borsh1::io::Result<()> {
297 self.to_primitive().serialize(writer)
298 }
299 }
300
301 #[cfg(feature = "borsh1_unstable__schema")]
302 #[allow(non_snake_case)]
303 mod borsh1_unstable__schema_impl {
304 use super::super::{
305 MathErrorsDivisionByZero, MathErrorsInvalidInput, MathErrorsOverflow,
306 MathErrorsUnderflow,
307 };
308 use super::*;
309 use alloc::string::ToString;
310 use borsh1::{
311 schema::{Definition, Fields},
312 BorshSchema,
313 };
314 impl BorshSchema for MathErrorsInvalidInput {
315 fn add_definitions_recursively(
316 definitions: &mut alloc::collections::btree_map::BTreeMap<
317 borsh1::schema::Declaration,
318 Definition,
319 >,
320 ) {
321 definitions.insert(
322 Self::declaration(),
323 Definition::Struct {
324 fields: Fields::Empty,
325 },
326 );
327 }
328
329 fn declaration() -> borsh1::schema::Declaration {
330 "MathErrorsInvalidInput".to_string()
331 }
332 }
333
334 impl BorshSchema for MathErrorsOverflow {
335 fn add_definitions_recursively(
336 definitions: &mut alloc::collections::btree_map::BTreeMap<
337 borsh1::schema::Declaration,
338 Definition,
339 >,
340 ) {
341 definitions.insert(
342 Self::declaration(),
343 Definition::Struct {
344 fields: Fields::Empty,
345 },
346 );
347 }
348
349 fn declaration() -> borsh1::schema::Declaration {
350 "MathErrorsOverflow".to_string()
351 }
352 }
353
354 impl BorshSchema for MathErrorsUnderflow {
355 fn add_definitions_recursively(
356 definitions: &mut alloc::collections::btree_map::BTreeMap<
357 borsh1::schema::Declaration,
358 Definition,
359 >,
360 ) {
361 definitions.insert(
362 Self::declaration(),
363 Definition::Struct {
364 fields: Fields::Empty,
365 },
366 );
367 }
368
369 fn declaration() -> borsh1::schema::Declaration {
370 "MathErrorsUnderflow".to_string()
371 }
372 }
373
374 impl BorshSchema for MathErrorsDivisionByZero {
375 fn add_definitions_recursively(
376 definitions: &mut alloc::collections::btree_map::BTreeMap<
377 borsh1::schema::Declaration,
378 Definition,
379 >,
380 ) {
381 definitions.insert(
382 Self::declaration(),
383 Definition::Struct {
384 fields: Fields::Empty,
385 },
386 );
387 }
388
389 fn declaration() -> borsh1::schema::Declaration {
390 "MathErrorsDivisionByZero".to_string()
391 }
392 }
393
394 impl BorshSchema for MathErrors {
395 fn add_definitions_recursively(
396 definitions: &mut alloc::collections::btree_map::BTreeMap<
397 borsh1::schema::Declaration,
398 borsh1::schema::Definition,
399 >,
400 ) {
401 MathErrorsInvalidInput::add_definitions_recursively(definitions);
402 MathErrorsOverflow::add_definitions_recursively(definitions);
403 MathErrorsUnderflow::add_definitions_recursively(definitions);
404 MathErrorsDivisionByZero::add_definitions_recursively(definitions);
405
406 let definition = Definition::Enum {
407 tag_width: 1,
408 variants: alloc::vec![
409 (
410 0,
411 "InvalidInput".to_string(),
412 <MathErrorsInvalidInput as BorshSchema>::declaration()
413 ),
414 (
415 1,
416 "Overflow".to_string(),
417 <MathErrorsOverflow as BorshSchema>::declaration()
418 ),
419 (
420 2,
421 "Underflow".to_string(),
422 <MathErrorsUnderflow as BorshSchema>::declaration()
423 ),
424 (
425 3,
426 "DivisionByZero".to_string(),
427 <MathErrorsDivisionByZero as BorshSchema>::declaration()
428 ),
429 ],
430 };
431
432 match definitions.entry(Self::declaration()) {
433 alloc::collections::btree_map::Entry::Vacant(vacant_entry) => {
434 vacant_entry.insert(definition);
435 }
436 alloc::collections::btree_map::Entry::Occupied(occupied_entry) => {
437 let other = occupied_entry.get();
438 assert_eq!(&definition, other, "definition must be same shape");
439 }
440 }
441 }
442
443 fn declaration() -> borsh1::schema::Declaration {
444 "MathErrors".to_string()
445 }
446 }
447 }
448}
449
450#[cfg(feature = "protobuf3")]
451mod protobuf3_impl {
452 use crate::*;
453 use protobuf3::Enum;
454
455 #[allow(clippy::derivable_impls)]
456 impl Default for MathErrors {
457 fn default() -> Self {
458 MathErrors::InvalidInput
459 }
460 }
461
462 impl Enum for MathErrors {
463 const NAME: &'static str = "MathErrors";
464
465 fn value(&self) -> i32 {
466 self.to_primitive().into()
467 }
468
469 fn from_i32(v: i32) -> Option<Self> {
470 match v {
471 0 => Some(Self::InvalidInput),
472 2 => Some(Self::Overflow),
473 3 => Some(Self::Underflow),
474 4 => Some(Self::DivisionByZero),
475 _ => None,
476 }
477 }
478
479 fn from_str(s: &str) -> Option<Self> {
480 match s {
481 "InvalidInput" => Some(Self::InvalidInput),
482 "Overflow" => Some(Self::Overflow),
483 "Underflow" => Some(Self::Underflow),
484 "DivisionByZero" => Some(Self::DivisionByZero),
485 _ => None,
486 }
487 }
488 const VALUES: &'static [Self] = &[
489 Self::InvalidInput,
490 Self::Overflow,
491 Self::Underflow,
492 Self::DivisionByZero,
493 ];
494 }
495}
496
497#[cfg(feature = "parity-scale-codec3")]
498mod parity_scale_codec3_impl {
499 use super::*;
500 use parity_scale_codec3::Encode;
501
502 impl Encode for MathErrors {
503 fn size_hint(&self) -> usize {
504 1
505 }
506
507 fn encode_to<T: parity_scale_codec3::Output + ?Sized>(&self, dest: &mut T) {
508 dest.push_byte(self.to_primitive());
509 }
510
511 fn encoded_size(&self) -> usize {
512 1
513 }
514 }
515}
516
517#[cfg(feature = "proptest1")]
518mod proptest1_impl {
519 use super::*;
520 use proptest1::{
521 prelude::{Arbitrary, BoxedStrategy, Just, Strategy},
522 prop_oneof,
523 };
524
525 impl Arbitrary for MathErrors {
526 type Parameters = ();
527 type Strategy = BoxedStrategy<Self>;
528
529 fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
530 prop_oneof![
531 Just(Self::Overflow),
532 Just(Self::Underflow),
533 Just(Self::DivisionByZero),
534 ]
535 .boxed()
536 }
537 }
538}
539
540#[cfg(feature = "arbitrary1")]
541mod arbitrary1_impl {
542 use super::*;
543 use arbitrary1::*;
544
545 impl<'a> Arbitrary<'a> for MathErrors {
546 fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
547 let value = u.int_in_range(0..=3)?;
548 Ok(Self::try_from_primitive(value).expect("with in range"))
549 }
550 }
551}
552
553#[cfg(feature = "arbitrary-int1")]
554mod arbitrary_int1_impl {
555 use super::*;
556 use arbitrary_int1::u2;
557
558 impl MathErrors {
559 pub const fn from_u2(value: u2) -> Self {
560 match value.value() {
561 0 => MathErrors::InvalidInput,
562 1 => MathErrors::Overflow,
563 2 => MathErrors::Underflow,
564 _ => MathErrors::DivisionByZero,
565 }
566 }
567
568 pub const fn to_primitive_u2(&self) -> u2 {
569 match self {
570 MathErrors::InvalidInput => u2::new(0),
571 MathErrors::Overflow => u2::new(1),
572 MathErrors::Underflow => u2::new(2),
573 MathErrors::DivisionByZero => u2::new(3),
574 }
575 }
576 }
577
578 impl Into<u2> for MathErrors {
579 fn into(self) -> u2 {
580 self.to_primitive_u2()
581 }
582 }
583
584 impl From<u2> for MathErrors {
585 fn from(value: u2) -> Self {
586 Self::from_u2(value)
587 }
588 }
589}
590
591#[cfg(feature = "error")]
592mod error_impl {
593 use super::*;
594 use core::error::Error;
595 impl Error for MathErrors {}
596
597 impl Error for MathError {}
598
599 impl Error for MathErrorsInvalidInput {}
600
601 impl Error for MathErrorsOverflow {}
602
603 impl Error for MathErrorsUnderflow {}
604
605 impl Error for MathErrorsDivisionByZero {}
606}