1#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
21pub enum Resolved<T> {
22 Fact(T),
24
25 Predict(T),
27}
28
29impl<T> Resolved<T> {
30 #[inline]
39 pub fn value(self) -> T {
40 match self {
41 Self::Fact(value) | Self::Predict(value) => value,
42 }
43 }
44
45 #[inline]
47 pub const fn is_fact(&self) -> bool {
48 matches!(self, Self::Fact(_))
49 }
50
51 #[inline]
53 pub const fn is_predict(&self) -> bool {
54 matches!(self, Self::Predict(_))
55 }
56
57 #[inline]
59 pub fn map<U>(self, f: impl FnOnce(T) -> U) -> Resolved<U> {
60 match self {
61 Self::Fact(value) => Resolved::Fact(f(value)),
62 Self::Predict(value) => Resolved::Predict(f(value)),
63 }
64 }
65
66 #[inline]
68 pub const fn as_ref(&self) -> Resolved<&T> {
69 match self {
70 Self::Fact(value) => Resolved::Fact(value),
71 Self::Predict(value) => Resolved::Predict(value),
72 }
73 }
74}
75
76#[cfg(feature = "serde")]
77impl<T: serde::Serialize> serde::Serialize for Resolved<T> {
78 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
79 use serde::ser::SerializeStruct;
80
81 let mut s = serializer.serialize_struct("Resolved", 2)?;
82 match self {
83 Self::Fact(value) => {
84 s.serialize_field("kind", "Fact")?;
85 s.serialize_field("value", value)?;
86 }
87 Self::Predict(value) => {
88 s.serialize_field("kind", "Predict")?;
89 s.serialize_field("value", value)?;
90 }
91 }
92 s.end()
93 }
94}
95
96#[cfg(feature = "serde")]
97impl<'de, T: serde::Deserialize<'de>> serde::Deserialize<'de> for Resolved<T> {
98 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
99 #[derive(serde::Deserialize)]
100 #[serde(field_identifier, rename_all = "snake_case")]
101 enum Field {
102 Kind,
103 Value,
104 }
105
106 struct Visitor<T>(std::marker::PhantomData<T>);
107
108 impl<'de, T: serde::Deserialize<'de>> serde::de::Visitor<'de> for Visitor<T> {
109 type Value = Resolved<T>;
110
111 fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
112 f.write_str("struct Resolved")
113 }
114
115 fn visit_map<A: serde::de::MapAccess<'de>>(
116 self,
117 mut map: A,
118 ) -> Result<Self::Value, A::Error> {
119 let mut kind: Option<String> = None;
120 let mut value: Option<T> = None;
121
122 while let Some(key) = map.next_key()? {
123 match key {
124 Field::Kind => {
125 if kind.is_some() {
126 return Err(serde::de::Error::duplicate_field("kind"));
127 }
128 kind = Some(map.next_value()?);
129 }
130 Field::Value => {
131 if value.is_some() {
132 return Err(serde::de::Error::duplicate_field("value"));
133 }
134 value = Some(map.next_value()?);
135 }
136 }
137 }
138
139 let kind = kind.ok_or_else(|| serde::de::Error::missing_field("kind"))?;
140 let value = value.ok_or_else(|| serde::de::Error::missing_field("value"))?;
141
142 match kind.as_str() {
143 "Fact" => Ok(Resolved::Fact(value)),
144 "Predict" => Ok(Resolved::Predict(value)),
145 other => Err(serde::de::Error::unknown_variant(
146 other,
147 &["Fact", "Predict"],
148 )),
149 }
150 }
151 }
152
153 deserializer.deserialize_struct(
154 "Resolved",
155 &["kind", "value"],
156 Visitor(std::marker::PhantomData),
157 )
158 }
159}
160
161#[cfg(all(test, feature = "serde"))]
162mod serde_tests {
163 use super::*;
164
165 #[test]
166 fn test_serde_json_fact_format() {
167 let value = Resolved::Fact(42u8);
168 let json = serde_json::to_string(&value).unwrap();
169
170 assert_eq!(json, r#"{"kind":"Fact","value":42}"#);
171 assert_eq!(serde_json::from_str::<Resolved<u8>>(&json).unwrap(), value);
172 }
173
174 #[test]
175 fn test_serde_json_predict_format() {
176 let value = Resolved::Predict(false);
177 let json = serde_json::to_string(&value).unwrap();
178
179 assert_eq!(json, r#"{"kind":"Predict","value":false}"#);
180 assert_eq!(
181 serde_json::from_str::<Resolved<bool>>(&json).unwrap(),
182 value
183 );
184 }
185}