1use serde::ser::{Serialize, Serializer};
2use std::fmt::Display;
3
4use crate::{value_display_fmt, Error, Signature, Type, Value};
5
6#[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
12pub struct Maybe<'a> {
13 value: Box<Option<Value<'a>>>,
14 signature: Signature,
15}
16
17impl<'a> Maybe<'a> {
18 pub fn inner(&self) -> &Option<Value<'a>> {
20 &self.value
21 }
22
23 pub fn just(value: Value<'a>) -> Self {
25 let value_signature = value.value_signature().clone();
26 let signature = Signature::maybe(value_signature);
27 Self {
28 signature,
29 value: Box::new(Some(value)),
30 }
31 }
32
33 pub(crate) fn just_full_signature(value: Value<'a>, signature: &Signature) -> Self {
34 Self {
35 signature: signature.clone(),
36 value: Box::new(Some(value)),
37 }
38 }
39
40 pub fn nothing(value_signature: &Signature) -> Self {
42 let signature = Signature::maybe(value_signature.clone());
43 Self {
44 signature,
45 value: Box::new(None),
46 }
47 }
48
49 pub(crate) fn nothing_full_signature(signature: &Signature) -> Self {
50 Self {
51 signature: signature.clone(),
52 value: Box::new(None),
53 }
54 }
55
56 pub fn get<T>(&'a self) -> core::result::Result<Option<T>, Error>
58 where
59 T: ?Sized + TryFrom<&'a Value<'a>>,
60 <T as TryFrom<&'a Value<'a>>>::Error: Into<crate::Error>,
61 {
62 self.value
63 .as_ref()
64 .as_ref()
65 .map(|v| v.downcast_ref())
66 .transpose()
67 }
68
69 pub fn signature(&self) -> &Signature {
71 &self.signature
72 }
73
74 pub fn value_signature(&self) -> &Signature {
76 match self.signature() {
77 Signature::Maybe(signature) => signature,
78 _ => unreachable!("Invalid `Maybe` signature"),
79 }
80 }
81
82 pub(crate) fn try_to_owned(&self) -> crate::Result<Maybe<'static>> {
83 Ok(Maybe {
84 value: Box::new(
85 self.value
86 .as_ref()
87 .as_ref()
88 .map(|v| v.try_to_owned().map(Into::into))
89 .transpose()?,
90 ),
91 signature: self.signature.clone(),
92 })
93 }
94
95 pub fn try_clone(&self) -> Result<Self, crate::Error> {
97 Ok(Maybe {
98 value: Box::new(
99 self.value
100 .as_ref()
101 .as_ref()
102 .map(|v| v.try_clone().map(Into::into))
103 .transpose()?,
104 ),
105 signature: self.signature.clone(),
106 })
107 }
108}
109
110impl Display for Maybe<'_> {
111 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
112 maybe_display_fmt(self, f, true)
113 }
114}
115
116pub(crate) fn maybe_display_fmt(
117 maybe: &Maybe<'_>,
118 f: &mut std::fmt::Formatter<'_>,
119 type_annotate: bool,
120) -> std::fmt::Result {
121 if type_annotate {
122 write!(f, "@{} ", maybe.signature())?;
123 }
124
125 let (last_inner, depth) = {
126 let mut curr = maybe.inner();
127 let mut depth = 0;
128
129 while let Some(Value::Maybe(child_maybe)) = curr {
130 curr = child_maybe.inner();
131 depth += 1;
132 }
133
134 (curr, depth)
135 };
136
137 if let Some(last_inner) = last_inner {
138 value_display_fmt(last_inner, f, false)?;
140 } else {
141 for _ in 0..depth {
143 f.write_str("just ")?;
144 }
145 f.write_str("nothing")?;
146 }
147
148 Ok(())
149}
150
151impl<'a, T> From<Option<T>> for Maybe<'a>
152where
153 T: Type + Into<Value<'a>>,
154{
155 fn from(value: Option<T>) -> Self {
156 value
157 .map(|v| Self::just(Value::new(v)))
158 .unwrap_or_else(|| Self::nothing(T::SIGNATURE))
159 }
160}
161
162impl<'a, T> From<&Option<T>> for Maybe<'a>
163where
164 T: Type + Into<Value<'a>> + Clone,
165{
166 fn from(value: &Option<T>) -> Self {
167 value
168 .as_ref()
169 .map(|v| Self::just(Value::new(v.clone())))
170 .unwrap_or_else(|| Self::nothing(T::SIGNATURE))
171 }
172}
173
174impl<'a> Serialize for Maybe<'a> {
175 fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
176 where
177 S: Serializer,
178 {
179 match &*self.value {
180 Some(value) => value.serialize_value_as_some(serializer),
181 None => serializer.serialize_none(),
182 }
183 }
184}