1use std::marker::PhantomData;
2
3use serde::{Deserialize, Deserializer, Serialize, Serializer};
4
5#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
8pub enum AbsentOr<T> {
9 #[default]
10 Absent,
11 Null,
12 Present(T),
13}
14
15impl<T> AbsentOr<T> {
16 #[inline]
17 pub fn is_absent(&self) -> bool {
18 matches!(self, Self::Absent)
19 }
20
21 #[inline]
22 pub fn is_null(&self) -> bool {
23 matches!(self, Self::Null)
24 }
25
26 #[inline]
27 pub fn is_present(&self) -> bool {
28 matches!(self, Self::Present(_))
29 }
30
31 #[inline]
32 pub fn ok(self) -> Result<T, AbsentError> {
33 match self {
34 Self::Absent => Err(AbsentError::Absent),
35 Self::Null => Err(AbsentError::Null),
36 Self::Present(value) => Ok(value),
37 }
38 }
39
40 #[inline]
41 pub fn as_ref(&self) -> AbsentOr<&T> {
42 match self {
43 Self::Absent => AbsentOr::Absent,
44 Self::Null => AbsentOr::Null,
45 Self::Present(value) => AbsentOr::Present(value),
46 }
47 }
48
49 #[inline]
50 pub fn into_option(self) -> Option<T> {
51 match self {
52 Self::Absent | Self::Null => None,
53 Self::Present(value) => Some(value),
54 }
55 }
56}
57
58impl<T> From<T> for AbsentOr<T> {
59 #[inline]
60 fn from(value: T) -> Self {
61 Self::Present(value)
62 }
63}
64
65impl<T: Serialize> Serialize for AbsentOr<T> {
66 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
67 match self {
68 Self::Absent | Self::Null => serializer.serialize_none(),
69 Self::Present(value) => serializer.serialize_some(value),
70 }
71 }
72}
73
74impl<'de, T: Deserialize<'de>> Deserialize<'de> for AbsentOr<T> {
75 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
76 struct Visitor<T>(PhantomData<T>);
77 impl<'de, T: Deserialize<'de>> serde::de::Visitor<'de> for Visitor<T> {
78 type Value = AbsentOr<T>;
79
80 fn expecting(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
81 f.write_str("`null` or value")
82 }
83
84 fn visit_unit<E: serde::de::Error>(self) -> Result<Self::Value, E> {
85 Ok(AbsentOr::Null)
86 }
87
88 fn visit_none<E: serde::de::Error>(self) -> Result<Self::Value, E> {
89 Ok(AbsentOr::Null)
90 }
91
92 fn visit_some<D: Deserializer<'de>>(
93 self,
94 deserializer: D,
95 ) -> Result<Self::Value, D::Error> {
96 T::deserialize(deserializer).map(AbsentOr::Present)
97 }
98 }
99 deserializer.deserialize_option(Visitor(PhantomData))
100 }
101}
102
103#[derive(Debug, thiserror::Error)]
104pub enum AbsentError {
105 #[error("value not present")]
106 Absent,
107 #[error("value is `null`")]
108 Null,
109}
110
111impl AbsentError {
112 #[inline]
113 pub fn field(self, name: &'static str) -> FieldAbsentError {
114 match self {
115 Self::Absent => FieldAbsentError::Absent(name),
116 Self::Null => FieldAbsentError::Null(name),
117 }
118 }
119}
120
121#[derive(Debug, thiserror::Error)]
122pub enum FieldAbsentError {
123 #[error("field `{0}` not present")]
124 Absent(&'static str),
125 #[error("field `{0}` is `null`")]
126 Null(&'static str),
127}