rbdc_sqlite/types/
value.rs

1use crate::decode::Decode;
2use crate::encode::{Encode, IsNull};
3use crate::type_info::DataType;
4use crate::{SqliteArgumentValue, SqliteValue};
5use rbdc::Error;
6use rbs::Value;
7
8impl Decode for Value {
9    fn decode(value: SqliteValue) -> Result<Self, Error>
10    where
11        Self: Sized,
12    {
13        if value.type_info_opt().is_none() {
14            return Ok(Value::Null);
15        }
16        match value.type_info().0 {
17            DataType::Null => Ok(Value::Null),
18            DataType::Int => Ok(Value::I64(i64::decode(value)?)),
19            DataType::Float => Ok(Value::F64(f64::decode(value)?)),
20            DataType::Text => {
21                let s = value.text()?;
22                if is_json_string(s) {
23                    if let Ok(v) = serde_json::from_str::<Value>(&s) {
24                        Ok(v)
25                    } else {
26                        Ok(Value::String(s.to_string()))
27                    }
28                } else {
29                    Ok(Value::String(s.to_string()))
30                }
31            }
32            DataType::Blob => Ok(Value::Binary(Vec::<u8>::decode(value)?)),
33            DataType::Numeric => Ok(Value::String(String::decode(value)?)),
34            DataType::Bool => Ok(Value::Bool(bool::decode(value)?)),
35            DataType::Int64 => Ok(Value::I64(i64::decode(value)?)),
36            DataType::Date => Ok(Value::Ext(
37                "Date",
38                Box::new(Value::String(String::decode(value)?)),
39            )),
40            DataType::Time => Ok(Value::Ext(
41                "Time",
42                Box::new(Value::String(String::decode(value)?)),
43            )),
44            DataType::Datetime => Ok(Value::Ext(
45                "Datetime",
46                Box::new(Value::String(String::decode(value)?)),
47            )),
48        }
49    }
50}
51
52impl Encode for Value {
53    fn encode(self, args: &mut Vec<SqliteArgumentValue>) -> Result<IsNull, Error> {
54        match self {
55            Value::Null => Ok(IsNull::Yes),
56            Value::Bool(v) => {
57                v.encode(args)?;
58                Ok(IsNull::No)
59            }
60            Value::I32(v) => {
61                v.encode(args)?;
62                Ok(IsNull::No)
63            }
64            Value::I64(v) => {
65                v.encode(args)?;
66                Ok(IsNull::No)
67            }
68            Value::U32(v) => {
69                (v as i32).encode(args)?;
70                Ok(IsNull::No)
71            }
72            Value::U64(v) => {
73                (v as i64).encode(args)?;
74                Ok(IsNull::No)
75            }
76            Value::F32(v) => {
77                v.encode(args)?;
78                Ok(IsNull::No)
79            }
80            Value::F64(v) => {
81                v.encode(args)?;
82                Ok(IsNull::No)
83            }
84            Value::String(v) => {
85                v.encode(args)?;
86                Ok(IsNull::No)
87            }
88            Value::Binary(v) => {
89                v.encode(args)?;
90                Ok(IsNull::No)
91            }
92            Value::Array(v) => {
93                //json
94                Value::Array(v).to_string().encode(args)?;
95                Ok(IsNull::No)
96            }
97            Value::Map(v) => {
98                //json
99                Value::Map(v).to_string().encode(args)?;
100                Ok(IsNull::No)
101            }
102            Value::Ext(t, v) => match t {
103                "Date" => {
104                    v.into_string().unwrap_or_default().encode(args)?;
105                    Ok(IsNull::No)
106                }
107                "DateTime" => {
108                    v.into_string().unwrap_or_default().encode(args)?;
109                    Ok(IsNull::No)
110                }
111                "Time" => {
112                    v.into_string().unwrap_or_default().encode(args)?;
113                    Ok(IsNull::No)
114                }
115                "Timestamp" => {
116                    v.as_i64().unwrap_or_default().encode(args)?;
117                    Ok(IsNull::No)
118                }
119                "Decimal" => {
120                    v.into_string().unwrap_or_default().encode(args)?;
121                    Ok(IsNull::No)
122                }
123                "Json" => {
124                    v.into_bytes().unwrap_or_default().encode(args)?;
125                    Ok(IsNull::No)
126                }
127                "Uuid" => {
128                    v.into_string().unwrap_or_default().encode(args)?;
129                    Ok(IsNull::No)
130                }
131                _ => Ok(IsNull::Yes),
132            },
133        }
134    }
135}
136
137//if is json null/map/array
138pub fn is_json_string(js: &str) -> bool {
139    if js == "null"
140        || js.starts_with("{") && js.ends_with("}")
141        || js.starts_with("[") && js.ends_with("]")
142    {
143        true
144    } else {
145        false
146    }
147}