1use super::*;
4
5use core::hash::Hasher;
6
7pub type MaybeMut<'a, T> = Maybe<T, &'a mut T>;
9
10pub type MaybeRef<'a, T> = Maybe<T, &'a T>;
12
13#[derive(Copy, Clone)]
17pub enum Maybe<T, R: Deref<Target = T>> {
18 Ref(R),
20 Val(T),
22}
23
24impl<T: PartialEq, R: Deref<Target = T>> PartialEq for Maybe<T, R> {
25 #[inline]
26 fn eq(&self, other: &Self) -> bool {
27 **self == **other
28 }
29}
30
31impl<T: Eq, R: Deref<Target = T>> Eq for Maybe<T, R> {}
32
33impl<T: PartialOrd, R: Deref<Target = T>> PartialOrd for Maybe<T, R> {
34 #[inline]
35 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
36 (**self).partial_cmp(&**other)
37 }
38}
39
40impl<T: Ord, R: Deref<Target = T>> Ord for Maybe<T, R> {
41 #[inline]
42 fn cmp(&self, other: &Self) -> Ordering {
43 (**self).cmp(&**other)
44 }
45}
46
47impl<T: Hash, R: Deref<Target = T>> Hash for Maybe<T, R> {
48 #[inline]
49 fn hash<H: Hasher>(&self, state: &mut H) {
50 T::hash(&**self, state)
51 }
52}
53
54impl<T: fmt::Debug, R: Deref<Target = T>> fmt::Debug for Maybe<T, R> {
55 #[inline]
56 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
57 T::fmt(&**self, f)
58 }
59}
60
61impl<T, R: Deref<Target = T>> Maybe<T, R> {
62 #[inline]
64 pub fn into_inner(self) -> T
65 where
66 T: Clone,
67 {
68 match self {
69 Self::Ref(x) => x.clone(),
70 Self::Val(x) => x,
71 }
72 }
73
74 #[inline]
76 pub fn into_owned<U>(self) -> Maybe<T, U>
77 where
78 T: Clone,
79 U: Deref<Target = T>,
80 {
81 Maybe::Val(self.into_inner())
82 }
83}
84
85impl<T, R: Deref<Target = T>> Deref for Maybe<T, R> {
86 type Target = T;
87
88 #[inline]
89 fn deref(&self) -> &Self::Target {
90 match self {
91 Self::Ref(x) => x,
92 Self::Val(x) => x,
93 }
94 }
95}
96
97impl<T, R: DerefMut<Target = T>> DerefMut for Maybe<T, R> {
98 #[inline]
99 fn deref_mut(&mut self) -> &mut Self::Target {
100 match self {
101 Self::Ref(x) => &mut *x,
102 Self::Val(x) => x,
103 }
104 }
105}
106
107impl<T> From<T> for Maybe<T, &T> {
108 #[inline]
109 fn from(x: T) -> Self {
110 Self::Val(x)
111 }
112}
113
114impl<T> From<T> for Maybe<T, &mut T> {
115 #[inline]
116 fn from(x: T) -> Self {
117 Self::Val(x)
118 }
119}
120
121impl<'a, T> From<&'a T> for Maybe<T, &'a T> {
122 #[inline]
123 fn from(x: &'a T) -> Self {
124 Self::Ref(x)
125 }
126}
127
128impl<'a, T> From<&'a mut T> for Maybe<T, &'a mut T> {
129 #[inline]
130 fn from(x: &'a mut T) -> Self {
131 Self::Ref(x)
132 }
133}
134
135#[cfg(feature = "serde")]
136impl<T: Serialize, R: Deref<Target = T>> Serialize for Maybe<T, R> {
137 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
138 where
139 S: Serializer,
140 {
141 serializer.serialize_newtype_struct("Maybe", &**self)
142 }
143}
144
145#[cfg(feature = "serde")]
146impl<'de, T: Deserialize<'de>, R: Deref<Target = T>> Deserialize<'de> for Maybe<T, R> {
147 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
148 where
149 D: Deserializer<'de>,
150 {
151 struct MaybeVisitor<T, R>(PhantomData<(T, R)>);
152
153 impl<'de2, T: Deserialize<'de2>, R: Deref<Target = T>> Visitor<'de2> for MaybeVisitor<T, R> {
154 type Value = Maybe<T, R>;
155
156 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
157 write!(formatter, "a Maybe")
158 }
159
160 fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
161 where
162 D: Deserializer<'de2>,
163 {
164 T::deserialize(deserializer).map(Maybe::Val)
165 }
166 }
167
168 deserializer.deserialize_newtype_struct("Maybe", MaybeVisitor(PhantomData))
169 }
170}
171
172mod ref_or_val_sealed {
173 pub trait Sealed<T> {}
174}
175
176pub trait IntoMaybe<'src, T: 'src>:
183 ref_or_val_sealed::Sealed<T> + Borrow<T> + Into<MaybeRef<'src, T>>
184{
185 #[doc(hidden)]
189 type Proj<U: 'src>: IntoMaybe<'src, U>;
190
191 #[doc(hidden)]
192 fn map_maybe<R: 'src>(
193 self,
194 f: impl FnOnce(&'src T) -> &'src R,
195 g: impl FnOnce(T) -> R,
196 ) -> Self::Proj<R>;
197}
198
199impl<T> ref_or_val_sealed::Sealed<T> for &T {}
200impl<'src, T> IntoMaybe<'src, T> for &'src T {
201 type Proj<U: 'src> = &'src U;
202 fn map_maybe<R: 'src>(
203 self,
204 f: impl FnOnce(&'src T) -> &'src R,
205 _g: impl FnOnce(T) -> R,
206 ) -> Self::Proj<R> {
207 f(self)
208 }
209}
210
211impl<T> ref_or_val_sealed::Sealed<T> for T {}
212impl<'src, T: 'src> IntoMaybe<'src, T> for T {
213 type Proj<U: 'src> = U;
214 fn map_maybe<R: 'src>(
215 self,
216 _f: impl FnOnce(&'src T) -> &'src R,
217 g: impl FnOnce(T) -> R,
218 ) -> Self::Proj<R> {
219 g(self)
220 }
221}