stripe_types/
serde_helpers.rs

1use miniserde::json::Number;
2use miniserde::json::Value as MiniValue;
3use serde::ser::{SerializeMap, SerializeSeq};
4use serde::{Serialize, Serializer};
5
6struct Wrapper<'a>(&'a miniserde::json::Value);
7
8impl Serialize for Wrapper<'_> {
9    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
10    where
11        S: Serializer,
12    {
13        match &self.0 {
14            MiniValue::Null => serializer.serialize_none(),
15            MiniValue::Bool(bool) => serializer.serialize_bool(*bool),
16            MiniValue::Number(num) => match num {
17                Number::U64(uint) => serializer.serialize_u64(*uint),
18                Number::I64(int) => serializer.serialize_i64(*int),
19                Number::F64(float) => serializer.serialize_f64(*float),
20            },
21            MiniValue::String(str) => serializer.serialize_str(str),
22            MiniValue::Array(items) => {
23                let mut seq = serializer.serialize_seq(Some(items.len()))?;
24                for item in items {
25                    seq.serialize_element(&Wrapper(item))?;
26                }
27                seq.end()
28            }
29            MiniValue::Object(items) => {
30                let mut seq = serializer.serialize_map(Some(items.len()))?;
31                for (key, v) in items {
32                    seq.serialize_entry(key, &Wrapper(v))?;
33                }
34                seq.end()
35            }
36        }
37    }
38}
39
40pub mod with_serde_json {
41    use miniserde::json::Value as MiniValue;
42    use serde::{Serialize, Serializer};
43
44    use crate::serde_helpers::Wrapper;
45
46    #[cfg(feature = "deserialize")]
47    pub fn deserialize<'de, D>(deserializer: D) -> Result<MiniValue, D::Error>
48    where
49        D: serde::Deserializer<'de>,
50    {
51        use serde::Deserialize;
52
53        use crate::serde_helpers::serde_json_to_mini;
54        let value = serde_json::Value::deserialize(deserializer)?;
55        serde_json_to_mini(value).ok_or_else(|| {
56            serde::de::Error::custom("could not convert serde_json::Value to miniserde::Value")
57        })
58    }
59
60    pub fn serialize<S: Serializer>(val: &MiniValue, s: S) -> Result<S::Ok, S::Error> {
61        Wrapper(val).serialize(s)
62    }
63}
64
65pub mod with_serde_json_opt {
66    use miniserde::json::Value as MiniValue;
67    use serde::Serializer;
68
69    use crate::serde_helpers::Wrapper;
70
71    #[cfg(feature = "deserialize")]
72    pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<MiniValue>, D::Error>
73    where
74        D: serde::Deserializer<'de>,
75    {
76        use crate::serde_helpers::serde_json_to_mini;
77        let value: Option<serde_json::Value> = serde::Deserialize::deserialize(deserializer)?;
78        match value {
79            None => Ok(None),
80            Some(s) => Ok(Some(serde_json_to_mini(s).ok_or_else(|| {
81                serde::de::Error::custom("could not convert serde_json::Value to miniserde::Value")
82            })?)),
83        }
84    }
85
86    pub fn serialize<S: Serializer>(val: &Option<MiniValue>, s: S) -> Result<S::Ok, S::Error> {
87        match val {
88            None => s.serialize_none(),
89            Some(v) => s.serialize_some(&Wrapper(v)),
90        }
91    }
92}
93
94#[cfg(feature = "deserialize")]
95fn serde_json_to_mini(val: serde_json::Value) -> Option<MiniValue> {
96    use miniserde::json::{Array, Object};
97    Some(match val {
98        serde_json::Value::Null => MiniValue::Null,
99        serde_json::Value::Bool(bool) => MiniValue::Bool(bool),
100        serde_json::Value::Number(num) => {
101            if let Some(float) = num.as_f64() {
102                MiniValue::Number(Number::F64(float))
103            } else if let Some(uint) = num.as_u64() {
104                MiniValue::Number(Number::U64(uint))
105            } else if let Some(int) = num.as_i64() {
106                MiniValue::Number(Number::I64(int))
107            } else {
108                return None;
109            }
110        }
111        serde_json::Value::String(str) => MiniValue::String(str),
112        serde_json::Value::Array(arr) => {
113            let arr_conv = arr.into_iter().map(serde_json_to_mini).collect::<Option<Vec<_>>>()?;
114            MiniValue::Array(Array::from_iter(arr_conv))
115        }
116        serde_json::Value::Object(obj) => {
117            let items = obj
118                .into_iter()
119                .map(|(key, val)| serde_json_to_mini(val).map(|v| (key, v)))
120                .collect::<Option<Vec<(String, MiniValue)>>>()?;
121            MiniValue::Object(Object::from_iter(items))
122        }
123    })
124}