1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Default, PartialEq, Eq)]
39pub enum Maybe<T> {
40 #[default]
41 Unspecified,
42 Specified(T),
43}
44
45impl<T> Maybe<T> {
46 pub fn is_unspecified(&self) -> bool {
47 matches!(self, Self::Unspecified)
48 }
49
50 pub fn map<U, F>(self, f: F) -> Maybe<U>
51 where
52 F: FnOnce(T) -> U,
53 {
54 match self {
55 Self::Unspecified => Maybe::Unspecified,
56 Self::Specified(x) => Maybe::Specified(f(x)),
57 }
58 }
59
60 pub fn unwrap_or_default(self) -> T
61 where
62 T: Default,
63 {
64 match self {
65 Self::Unspecified => T::default(),
66 Self::Specified(x) => x,
67 }
68 }
69}
70
71impl<T> Maybe<Option<T>> {
72 pub fn map_opt<U, F>(self, f: F) -> Maybe<Option<U>>
73 where
74 F: FnOnce(T) -> U,
75 {
76 self.map(|opt| opt.map(f))
77 }
78
79 pub fn try_map_opt<U, E, F>(self, f: F) -> Result<Maybe<Option<U>>, E>
80 where
81 F: FnOnce(T) -> Result<U, E>,
82 {
83 match self {
84 Maybe::Unspecified => Ok(Maybe::Unspecified),
85 Maybe::Specified(opt) => match opt {
86 Some(value) => f(value).map(|converted| Maybe::Specified(Some(converted))),
87 None => Ok(Maybe::Specified(None)),
88 },
89 }
90 }
91}
92
93impl<T> From<T> for Maybe<T> {
94 fn from(value: T) -> Self {
95 Self::Specified(value)
96 }
97}
98
99impl<T: Serialize> Serialize for Maybe<T> {
100 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
101 where
102 S: serde::Serializer,
103 {
104 match self {
105 Self::Unspecified => serializer.serialize_none(),
106 Self::Specified(v) => v.serialize(serializer),
107 }
108 }
109}
110
111impl<'de, T: Deserialize<'de>> Deserialize<'de> for Maybe<T> {
112 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
113 where
114 D: serde::Deserializer<'de>,
115 {
116 let v = T::deserialize(deserializer)?;
117 Ok(v.into())
118 }
119}