Skip to main content

rustbasic_core/support/
casts.rs

1use serde::{Deserialize, Deserializer, Serializer};
2use serde_json::Value;
3
4/// Custom deserializer for boolean that handles SQLite/MySQL 0/1 integers
5pub fn deserialize_bool<'de, D>(deserializer: D) -> Result<bool, D::Error>
6where
7    D: Deserializer<'de>,
8{
9    let v = Value::deserialize(deserializer)?;
10    match v {
11        Value::Bool(b) => Ok(b),
12        Value::Number(n) => {
13            if let Some(i) = n.as_i64() {
14                Ok(i != 0)
15            } else {
16                Ok(false)
17            }
18        }
19        Value::String(ref s) => {
20            Ok(s == "1" || s.to_lowercase() == "true")
21        }
22        _ => Ok(false),
23    }
24}
25
26pub fn serialize_bool<S>(value: &bool, serializer: S) -> Result<S::Ok, S::Error>
27where
28    S: Serializer,
29{
30    serializer.serialize_bool(*value)
31}
32
33/// Custom deserializer for Option<bool> that handles SQLite/MySQL 0/1 integers
34pub fn deserialize_option_bool<'de, D>(deserializer: D) -> Result<Option<bool>, D::Error>
35where
36    D: Deserializer<'de>,
37{
38    let opt = Option::<Value>::deserialize(deserializer)?;
39    match opt {
40        Some(Value::Bool(b)) => Ok(Some(b)),
41        Some(Value::Number(n)) => {
42            if let Some(i) = n.as_i64() {
43                Ok(Some(i != 0))
44            } else {
45                Ok(Some(false))
46            }
47        }
48        Some(Value::String(ref s)) => {
49            Ok(Some(s == "1" || s.to_lowercase() == "true"))
50        }
51        _ => Ok(None),
52    }
53}
54
55pub fn serialize_option_bool<S>(value: &Option<bool>, serializer: S) -> Result<S::Ok, S::Error>
56where
57    S: Serializer,
58{
59    match value {
60        Some(b) => serializer.serialize_some(b),
61        None => serializer.serialize_none(),
62    }
63}
64
65/// Custom deserializer for JSON TEXT columns in database
66pub fn deserialize_json<'de, D>(deserializer: D) -> Result<Value, D::Error>
67where
68    D: Deserializer<'de>,
69{
70    let v = Value::deserialize(deserializer)?;
71    match v {
72        Value::String(ref s) => {
73            if s.is_empty() {
74                Ok(Value::Null)
75            } else {
76                serde_json::from_str(s).map_err(serde::de::Error::custom)
77            }
78        }
79        other => Ok(other),
80    }
81}
82
83pub fn serialize_json<S>(value: &Value, serializer: S) -> Result<S::Ok, S::Error>
84where
85    S: Serializer,
86{
87    let s = serde_json::to_string(value).map_err(serde::ser::Error::custom)?;
88    serializer.serialize_str(&s)
89}
90
91/// Custom deserializer for Option<Value> JSON TEXT columns in database
92pub fn deserialize_option_json<'de, D>(deserializer: D) -> Result<Option<Value>, D::Error>
93where
94    D: Deserializer<'de>,
95{
96    let opt = Option::<Value>::deserialize(deserializer)?;
97    match opt {
98        Some(Value::String(ref s)) => {
99            if s.is_empty() || s == "null" {
100                Ok(None)
101            } else {
102                let val = serde_json::from_str(s).map_err(serde::de::Error::custom)?;
103                Ok(Some(val))
104            }
105        }
106        Some(other) => Ok(Some(other)),
107        None => Ok(None),
108    }
109}
110
111pub fn serialize_option_json<S>(value: &Option<Value>, serializer: S) -> Result<S::Ok, S::Error>
112where
113    S: Serializer,
114{
115    match value {
116        Some(val) => {
117            let s = serde_json::to_string(val).map_err(serde::ser::Error::custom)?;
118            serializer.serialize_some(&s)
119        }
120        None => serializer.serialize_none(),
121    }
122}