1use core::{fmt, num::NonZeroU32};
2
3use serde::{
4 de::{Deserialize, Deserializer, Visitor},
5 Serialize, Serializer,
6};
7
8#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord, Default)]
16pub enum Code {
17 #[default]
19 Ok,
20
21 Err(NonZeroU32),
23}
24
25impl Code {
26 pub fn is_ok(self) -> bool {
28 match self {
29 Code::Ok => true,
30 Code::Err(_) => false,
31 }
32 }
33
34 pub fn is_err(self) -> bool {
36 !self.is_ok()
37 }
38
39 pub fn value(self) -> u32 {
41 u32::from(self)
42 }
43}
44
45impl From<u32> for Code {
46 fn from(value: u32) -> Code {
47 match NonZeroU32::new(value) {
48 Some(value) => Code::Err(value),
49 None => Code::Ok,
50 }
51 }
52}
53
54impl From<Code> for u32 {
55 fn from(code: Code) -> u32 {
56 match code {
57 Code::Ok => 0,
58 Code::Err(err) => err.get(),
59 }
60 }
61}
62
63impl Serialize for Code {
64 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
65 self.value().serialize(serializer)
66 }
67}
68
69impl<'de> Deserialize<'de> for Code {
70 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
71 where
72 D: Deserializer<'de>,
73 {
74 struct CodeVisitor;
75
76 impl<'de> Visitor<'de> for CodeVisitor {
77 type Value = Code;
78
79 fn expecting(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
80 fmt.write_str("integer or string")
81 }
82
83 fn visit_u64<E>(self, val: u64) -> Result<Self::Value, E>
84 where
85 E: serde::de::Error,
86 {
87 Ok(Code::from(val as u32))
88 }
89
90 fn visit_str<E>(self, val: &str) -> Result<Self::Value, E>
91 where
92 E: serde::de::Error,
93 {
94 match val.parse::<u64>() {
95 Ok(val) => self.visit_u64(val),
96 Err(_) => Err(E::custom("failed to parse integer")),
97 }
98 }
99 }
100
101 deserializer.deserialize_any(CodeVisitor)
102 }
103}