rbdc_sqlite/types/
value.rs1use 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 Value::Array(v).to_string().encode(args)?;
95 Ok(IsNull::No)
96 }
97 Value::Map(v) => {
98 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
137pub 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}