1use std::collections::BTreeMap;
34use std::fmt;
35
36use serde::de::{DeserializeOwned, Deserializer, MapAccess, SeqAccess, Visitor};
37use serde::Deserialize;
38
39#[derive(Debug, Clone, PartialEq, Default)]
53pub enum WhiskerValue {
54 #[default]
55 Null,
56 Bool(bool),
57 Int(i64),
58 Float(f64),
59 String(String),
60 Bytes(Vec<u8>),
61 Array(Vec<WhiskerValue>),
62 Map(BTreeMap<String, WhiskerValue>),
67 Error(String),
71}
72
73impl WhiskerValue {
74 pub fn map<I, K>(entries: I) -> Self
79 where
80 I: IntoIterator<Item = (K, WhiskerValue)>,
81 K: Into<String>,
82 {
83 let mut m = BTreeMap::new();
84 for (k, v) in entries {
85 m.insert(k.into(), v);
86 }
87 WhiskerValue::Map(m)
88 }
89
90 pub fn args<I>(items: I) -> Self
97 where
98 I: IntoIterator<Item = WhiskerValue>,
99 {
100 WhiskerValue::map([("args", WhiskerValue::Array(items.into_iter().collect()))])
101 }
102
103 pub fn as_error(&self) -> Option<&str> {
107 if let WhiskerValue::Error(msg) = self {
108 Some(msg.as_str())
109 } else {
110 None
111 }
112 }
113
114 pub fn deserialize_into<T: DeserializeOwned>(&self) -> Result<T, String> {
124 serde_json::from_value(self.to_json()).map_err(|e| e.to_string())
125 }
126
127 pub fn to_json(&self) -> serde_json::Value {
130 use serde_json::Value as J;
131 match self {
132 WhiskerValue::Null => J::Null,
133 WhiskerValue::Bool(b) => J::Bool(*b),
134 WhiskerValue::Int(i) => J::Number((*i).into()),
135 WhiskerValue::Float(f) => serde_json::Number::from_f64(*f)
136 .map(J::Number)
137 .unwrap_or(J::Null),
138 WhiskerValue::String(s) => J::String(s.clone()),
139 WhiskerValue::Bytes(b) => {
143 J::Array(b.iter().map(|x| J::Number((*x as u64).into())).collect())
144 }
145 WhiskerValue::Array(a) => J::Array(a.iter().map(WhiskerValue::to_json).collect()),
146 WhiskerValue::Map(m) => {
147 J::Object(m.iter().map(|(k, v)| (k.clone(), v.to_json())).collect())
148 }
149 WhiskerValue::Error(e) => J::String(e.clone()),
153 }
154 }
155
156 pub fn from_json(v: serde_json::Value) -> WhiskerValue {
158 use serde_json::Value as J;
159 match v {
160 J::Null => WhiskerValue::Null,
161 J::Bool(b) => WhiskerValue::Bool(b),
162 J::Number(n) => {
163 if let Some(i) = n.as_i64() {
164 WhiskerValue::Int(i)
165 } else if let Some(f) = n.as_f64() {
166 WhiskerValue::Float(f)
167 } else {
168 WhiskerValue::Null
169 }
170 }
171 J::String(s) => WhiskerValue::String(s),
172 J::Array(a) => {
173 WhiskerValue::Array(a.into_iter().map(WhiskerValue::from_json).collect())
174 }
175 J::Object(o) => WhiskerValue::Map(
176 o.into_iter()
177 .map(|(k, v)| (k, WhiskerValue::from_json(v)))
178 .collect(),
179 ),
180 }
181 }
182}
183
184impl<'de> Deserialize<'de> for WhiskerValue {
190 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
191 where
192 D: Deserializer<'de>,
193 {
194 struct WhiskerValueVisitor;
195
196 impl<'de> Visitor<'de> for WhiskerValueVisitor {
197 type Value = WhiskerValue;
198
199 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
200 f.write_str("any JSON-compatible value")
201 }
202
203 fn visit_unit<E>(self) -> Result<WhiskerValue, E> {
204 Ok(WhiskerValue::Null)
205 }
206 fn visit_none<E>(self) -> Result<WhiskerValue, E> {
207 Ok(WhiskerValue::Null)
208 }
209 fn visit_some<D>(self, d: D) -> Result<WhiskerValue, D::Error>
210 where
211 D: Deserializer<'de>,
212 {
213 Deserialize::deserialize(d)
214 }
215 fn visit_bool<E>(self, v: bool) -> Result<WhiskerValue, E> {
216 Ok(WhiskerValue::Bool(v))
217 }
218 fn visit_i64<E>(self, v: i64) -> Result<WhiskerValue, E> {
219 Ok(WhiskerValue::Int(v))
220 }
221 fn visit_u64<E>(self, v: u64) -> Result<WhiskerValue, E> {
222 Ok(i64::try_from(v).map_or(WhiskerValue::Float(v as f64), WhiskerValue::Int))
223 }
224 fn visit_f64<E>(self, v: f64) -> Result<WhiskerValue, E> {
225 Ok(WhiskerValue::Float(v))
226 }
227 fn visit_str<E>(self, v: &str) -> Result<WhiskerValue, E> {
228 Ok(WhiskerValue::String(v.to_owned()))
229 }
230 fn visit_string<E>(self, v: String) -> Result<WhiskerValue, E> {
231 Ok(WhiskerValue::String(v))
232 }
233 fn visit_bytes<E>(self, v: &[u8]) -> Result<WhiskerValue, E> {
234 Ok(WhiskerValue::Bytes(v.to_owned()))
235 }
236 fn visit_seq<A>(self, mut seq: A) -> Result<WhiskerValue, A::Error>
237 where
238 A: SeqAccess<'de>,
239 {
240 let mut out = Vec::new();
241 while let Some(item) = seq.next_element()? {
242 out.push(item);
243 }
244 Ok(WhiskerValue::Array(out))
245 }
246 fn visit_map<A>(self, mut map: A) -> Result<WhiskerValue, A::Error>
247 where
248 A: MapAccess<'de>,
249 {
250 let mut out = BTreeMap::new();
251 while let Some((k, v)) = map.next_entry::<String, WhiskerValue>()? {
252 out.insert(k, v);
253 }
254 Ok(WhiskerValue::Map(out))
255 }
256 }
257
258 deserializer.deserialize_any(WhiskerValueVisitor)
259 }
260}
261
262#[derive(Debug, Clone, PartialEq, Eq)]
272pub struct WhiskerModuleError(pub String);
273
274impl std::fmt::Display for WhiskerModuleError {
275 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
276 f.write_str(&self.0)
277 }
278}
279
280impl std::error::Error for WhiskerModuleError {}
281
282impl From<()> for WhiskerValue {
283 fn from(_: ()) -> Self {
284 WhiskerValue::Null
285 }
286}
287impl From<bool> for WhiskerValue {
288 fn from(v: bool) -> Self {
289 WhiskerValue::Bool(v)
290 }
291}
292impl From<i32> for WhiskerValue {
293 fn from(v: i32) -> Self {
294 WhiskerValue::Int(v as i64)
295 }
296}
297impl From<i64> for WhiskerValue {
298 fn from(v: i64) -> Self {
299 WhiskerValue::Int(v)
300 }
301}
302impl From<u32> for WhiskerValue {
303 fn from(v: u32) -> Self {
304 WhiskerValue::Int(v as i64)
305 }
306}
307impl From<f32> for WhiskerValue {
308 fn from(v: f32) -> Self {
309 WhiskerValue::Float(v as f64)
310 }
311}
312impl From<f64> for WhiskerValue {
313 fn from(v: f64) -> Self {
314 WhiskerValue::Float(v)
315 }
316}
317impl From<String> for WhiskerValue {
318 fn from(v: String) -> Self {
319 WhiskerValue::String(v)
320 }
321}
322impl From<&str> for WhiskerValue {
323 fn from(v: &str) -> Self {
324 WhiskerValue::String(v.to_string())
325 }
326}
327impl From<Vec<u8>> for WhiskerValue {
328 fn from(v: Vec<u8>) -> Self {
329 WhiskerValue::Bytes(v)
330 }
331}
332impl<T> From<Vec<T>> for WhiskerValue
333where
334 T: Into<WhiskerValue>,
335{
336 fn from(v: Vec<T>) -> Self {
337 WhiskerValue::Array(v.into_iter().map(Into::into).collect())
338 }
339}
340
341impl TryFrom<WhiskerValue> for () {
347 type Error = String;
348 fn try_from(v: WhiskerValue) -> Result<Self, Self::Error> {
349 match v {
350 WhiskerValue::Null => Ok(()),
351 other => Err(format!("expected Null, got {other:?}")),
352 }
353 }
354}
355
356impl TryFrom<WhiskerValue> for bool {
357 type Error = String;
358 fn try_from(v: WhiskerValue) -> Result<Self, Self::Error> {
359 match v {
360 WhiskerValue::Bool(b) => Ok(b),
361 other => Err(format!("expected Bool, got {other:?}")),
362 }
363 }
364}
365
366impl TryFrom<WhiskerValue> for i64 {
367 type Error = String;
368 fn try_from(v: WhiskerValue) -> Result<Self, Self::Error> {
369 match v {
370 WhiskerValue::Int(i) => Ok(i),
371 other => Err(format!("expected Int, got {other:?}")),
372 }
373 }
374}
375
376impl TryFrom<WhiskerValue> for i32 {
377 type Error = String;
378 fn try_from(v: WhiskerValue) -> Result<Self, Self::Error> {
379 match v {
380 WhiskerValue::Int(i) => {
381 i32::try_from(i).map_err(|_| format!("Int {i} out of range for i32"))
382 }
383 other => Err(format!("expected Int, got {other:?}")),
384 }
385 }
386}
387
388impl TryFrom<WhiskerValue> for f64 {
389 type Error = String;
390 fn try_from(v: WhiskerValue) -> Result<Self, Self::Error> {
391 match v {
392 WhiskerValue::Float(f) => Ok(f),
393 WhiskerValue::Int(i) => Ok(i as f64),
396 other => Err(format!("expected Float, got {other:?}")),
397 }
398 }
399}
400
401impl TryFrom<WhiskerValue> for f32 {
402 type Error = String;
403 fn try_from(v: WhiskerValue) -> Result<Self, Self::Error> {
404 f64::try_from(v).map(|f| f as f32)
405 }
406}
407
408impl TryFrom<WhiskerValue> for String {
409 type Error = String;
410 fn try_from(v: WhiskerValue) -> Result<Self, Self::Error> {
411 match v {
412 WhiskerValue::String(s) => Ok(s),
413 other => Err(format!("expected String, got {other:?}")),
414 }
415 }
416}
417
418impl TryFrom<WhiskerValue> for Vec<u8> {
419 type Error = String;
420 fn try_from(v: WhiskerValue) -> Result<Self, Self::Error> {
421 match v {
422 WhiskerValue::Bytes(b) => Ok(b),
423 other => Err(format!("expected Bytes, got {other:?}")),
424 }
425 }
426}