1#[derive(Debug, Clone)]
2pub enum Value {
3 Bool(Option<bool>),
4 Binary(Option<Vec<u8>>),
6 Short(Option<i16>),
7 Int(Option<i32>),
8 Long(Option<i64>),
9 Float(Option<f32>),
10 Double(Option<f64>),
11 Text(Option<String>),
12 ChronoDate(Option<chrono::NaiveDateTime>),
13
14 Array(Vec<Self>),
15}
16
17use chrono::NaiveDateTime;
18use sqlx::Database;
19
20impl Value {
21 pub fn len(&self) -> usize {
22 match self {
23 Value::Array(ary) => ary.len(),
24 _ => 1,
25 }
26 }
27
28 pub fn add_param_value(&self, str: &mut String) {
29 if !str.is_empty() {
30 str.push_str(",");
31 }
32 str.push_str(&self.as_string());
33 }
34
35 pub fn as_string(&self) -> String {
36 match self {
37 Value::Int(val) => {
38 if let Some(v) = val {
39 format!("{}", v)
40 } else {
41 "null".to_string()
42 }
43 }
44 Value::Long(val) => {
45 if let Some(v) = val {
46 format!("{}", v)
47 } else {
48 "null".to_string()
49 }
50 }
51 Value::Double(val) => {
52 if let Some(v) = val {
53 format!("{}", v)
54 } else {
55 "null".to_string()
56 }
57 }
58 Value::ChronoDate(val) => {
59 if let Some(v) = val {
60 format!("{}", v)
61 } else {
62 "null".to_string()
63 }
64 }
65 Value::Text(val) => {
66 if let Some(v) = val {
67 format!("{}", v)
68 } else {
69 "null".to_string()
70 }
71 }
72 Value::Binary(val) => {
73 if let Some(v) = val {
74 format!("{:?}", v)
75 } else {
76 "null".to_string()
77 }
78 }
79 Value::Short(val) => {
80 if let Some(v) = val {
81 format!("{}", v)
82 } else {
83 "null".to_string()
84 }
85 }
86 Value::Float(val) => {
87 if let Some(v) = val {
88 format!("{}", v)
89 } else {
90 "null".to_string()
91 }
92 }
93 Value::Bool(val) => {
94 if let Some(v) = val {
95 format!("{}", v)
96 } else {
97 "null".to_string()
98 }
99 }
100 Value::Array(ary) => {
101 let ary_str: Vec<String> = ary.iter().map(|v| v.as_string()).collect();
102 format!("({})", ary_str.join(","))
103 }
111 }
112 }
113
114 pub fn bind_to_query<'a, DB: Database>(
115 &self,
116 query: sqlx::query::Query<'a, DB, DB::Arguments<'a>>,
117 ) -> sqlx::query::Query<'a, DB, DB::Arguments<'a>>
118 where
119 Option<bool>: sqlx::Encode<'a, DB> + sqlx::Decode<'a, DB>,
120 bool: sqlx::Type<DB>,
121 Option<i16>: sqlx::Encode<'a, DB> + sqlx::Decode<'a, DB>,
122 i16: sqlx::Type<DB>,
123 Option<i32>: sqlx::Encode<'a, DB> + sqlx::Decode<'a, DB>,
124 i32: sqlx::Type<DB>,
125 Option<i64>: sqlx::Encode<'a, DB> + sqlx::Decode<'a, DB>,
126 i64: sqlx::Type<DB>,
127 Option<f64>: sqlx::Encode<'a, DB> + sqlx::Decode<'a, DB>,
128 f64: sqlx::Type<DB>,
129 Option<f32>: sqlx::Encode<'a, DB> + sqlx::Decode<'a, DB>,
130 f32: sqlx::Type<DB>,
131 Option<NaiveDateTime>: sqlx::Encode<'a, DB> + sqlx::Decode<'a, DB>,
132 NaiveDateTime: sqlx::Type<DB>,
133 Option<String>: sqlx::Encode<'a, DB> + sqlx::Decode<'a, DB>,
134 String: sqlx::Type<DB>,
135 Option<Vec<u8>>: sqlx::Encode<'a, DB> + sqlx::Decode<'a, DB>,
136 Vec<u8>: sqlx::Type<DB>,
137 {
138 return match self {
139 Value::Int(val) => query.bind(*val),
140 Value::Long(val) => query.bind(*val),
141 Value::Double(val) => query.bind(*val),
142 Value::ChronoDate(val) => query.bind(*val),
143 Value::Text(val) => query.bind(val.clone()),
144 Value::Binary(val) => query.bind(val.clone()),
145 Value::Short(val) => query.bind(*val),
146 Value::Float(val) => query.bind(*val),
147 Value::Bool(val) => query.bind(*val),
148 Value::Array(ary) => {
149 let mut qry = query;
150 if !ary.is_empty() {
151 for val in ary {
152 qry = val.bind_to_query(qry);
153 }
154 }
155 qry
156 }
157 };
158 }
159
160 pub fn bind_to_query_as<'a, O, DB: Database>(
161 &self,
162 query: sqlx::query::QueryAs<'a, DB, O, DB::Arguments<'a>>,
163 ) -> sqlx::query::QueryAs<'a, DB, O, DB::Arguments<'a>>
164 where
165 Option<bool>: sqlx::Encode<'a, DB> + sqlx::Decode<'a, DB>,
166 bool: sqlx::Type<DB>,
167 Option<i16>: sqlx::Encode<'a, DB> + sqlx::Decode<'a, DB>,
168 i16: sqlx::Type<DB>,
169 Option<i32>: sqlx::Encode<'a, DB> + sqlx::Decode<'a, DB>,
170 i32: sqlx::Type<DB>,
171 Option<i64>: sqlx::Encode<'a, DB> + sqlx::Decode<'a, DB>,
172 i64: sqlx::Type<DB>,
173 Option<f64>: sqlx::Encode<'a, DB> + sqlx::Decode<'a, DB>,
174 f64: sqlx::Type<DB>,
175 Option<f32>: sqlx::Encode<'a, DB> + sqlx::Decode<'a, DB>,
176 f32: sqlx::Type<DB>,
177 Option<NaiveDateTime>: sqlx::Encode<'a, DB> + sqlx::Decode<'a, DB>,
178 NaiveDateTime: sqlx::Type<DB>,
179 Option<String>: sqlx::Encode<'a, DB> + sqlx::Decode<'a, DB>,
180 String: sqlx::Type<DB>,
181 Option<Vec<u8>>: sqlx::Encode<'a, DB> + sqlx::Decode<'a, DB>,
182 Vec<u8>: sqlx::Type<DB>,
183 {
184 return match self {
185 Value::Int(val) => query.bind(*val),
186 Value::Long(val) => query.bind(*val),
187 Value::Double(val) => query.bind(*val),
188 Value::ChronoDate(val) => query.bind(*val),
189 Value::Text(val) => query.bind(val.clone()),
190 Value::Binary(val) => query.bind(val.clone()),
191 Value::Short(val) => query.bind(*val),
192 Value::Float(val) => query.bind(*val),
193 Value::Bool(val) => query.bind(*val),
194 Value::Array(ary) => {
195 let mut qry = query;
196 if !ary.is_empty() {
197 for val in ary {
198 qry = val.bind_to_query_as(qry);
199 }
200 }
201 qry
202 }
203 };
204 }
205
206 pub fn bind_to_query_scalar<'a, O, DB: Database>(
207 &self,
208 query: sqlx::query::QueryScalar<'a, DB, O, DB::Arguments<'a>>,
209 ) -> sqlx::query::QueryScalar<'a, DB, O, DB::Arguments<'a>>
210 where
211 Option<bool>: sqlx::Encode<'a, DB> + sqlx::Decode<'a, DB>,
212 bool: sqlx::Type<DB>,
213 Option<i16>: sqlx::Encode<'a, DB> + sqlx::Decode<'a, DB>,
214 i16: sqlx::Type<DB>,
215 Option<i32>: sqlx::Encode<'a, DB> + sqlx::Decode<'a, DB>,
216 i32: sqlx::Type<DB>,
217 Option<i64>: sqlx::Encode<'a, DB> + sqlx::Decode<'a, DB>,
218 i64: sqlx::Type<DB>,
219 Option<f64>: sqlx::Encode<'a, DB> + sqlx::Decode<'a, DB>,
220 f64: sqlx::Type<DB>,
221 Option<f32>: sqlx::Encode<'a, DB> + sqlx::Decode<'a, DB>,
222 f32: sqlx::Type<DB>,
223 Option<NaiveDateTime>: sqlx::Encode<'a, DB> + sqlx::Decode<'a, DB>,
224 NaiveDateTime: sqlx::Type<DB>,
225 Option<String>: sqlx::Encode<'a, DB> + sqlx::Decode<'a, DB>,
226 String: sqlx::Type<DB>,
227 Option<Vec<u8>>: sqlx::Encode<'a, DB> + sqlx::Decode<'a, DB>,
228 Vec<u8>: sqlx::Type<DB>,
229 {
230 return match self {
231 Value::Int(val) => query.bind(*val),
232 Value::Long(val) => query.bind(*val),
233 Value::Double(val) => query.bind(*val),
234 Value::ChronoDate(val) => query.bind(*val),
235 Value::Text(val) => query.bind(val.clone()),
236 Value::Binary(val) => query.bind(val.clone()),
237 Value::Short(val) => query.bind(*val),
238 Value::Float(val) => query.bind(*val),
239 Value::Bool(val) => query.bind(*val),
240 Value::Array(ary) => {
241 let mut qry = query;
242 if !ary.is_empty() {
243 for val in ary {
244 qry = val.bind_to_query_scalar(qry);
245 }
246 }
247 qry
248 }
249 };
250 }
251}
252
253macro_rules! impl_from_num_for_value {
260 ($t:ty, $v:ident) => {
261 impl From<$t> for Value {
262 fn from(value: $t) -> Self {
263 Value::$v(Some(value))
264 }
265 }
266
267 impl From<&$t> for Value {
268 fn from(value: &$t) -> Self {
269 Value::$v(Some(*value))
270 }
271 }
272
273 impl From<Option<$t>> for Value {
274 fn from(value: Option<$t>) -> Self {
275 Value::$v(value)
276 }
277 }
278 };
279}
280
281macro_rules! impl_from_unsigned_num_for_value {
282 ($t:ty, $v:ident, $target:ty) => {
283 impl From<$t> for Value {
284 fn from(value: $t) -> Self {
285 Value::$v(Some(value as $target))
286 }
287 }
288
289 impl From<&$t> for Value {
290 fn from(value: &$t) -> Self {
291 Value::$v(Some(*value as $target))
292 }
293 }
294
295 impl From<Option<$t>> for Value {
296 fn from(value: Option<$t>) -> Self {
297 if let Some(val) = value {
298 Value::$v(Some(val as $target))
299 } else {
300 Value::$v(None)
301 }
302 }
303 }
304 };
305}
306
307macro_rules! impl_from_clone_for_value {
308 ($t:ty, $v:ident) => {
309 impl From<$t> for Value {
310 fn from(value: $t) -> Self {
311 Value::$v(Some(value.to_owned()))
312 }
313 }
314
315 impl From<&$t> for Value {
316 fn from(value: &$t) -> Self {
317 Value::$v(Some(value.clone()))
318 }
319 }
320
321 impl From<Option<$t>> for Value {
322 fn from(value: Option<$t>) -> Self {
323 Value::$v(value.clone())
324 }
325 }
326 };
327}
328
329impl_from_num_for_value!(bool, Bool);
330
331impl_from_num_for_value!(i16, Short);
332impl_from_num_for_value!(i32, Int);
333impl_from_num_for_value!(i64, Long);
334impl_from_unsigned_num_for_value!(u16, Short, i16);
336impl_from_unsigned_num_for_value!(u32, Int, i32);
337impl_from_unsigned_num_for_value!(u64, Long, i64);
338impl_from_clone_for_value!(Vec<u8>, Binary);
339impl_from_num_for_value!(f64, Double);
340impl_from_num_for_value!(f32, Float);
341impl_from_clone_for_value!(chrono::NaiveDateTime, ChronoDate);
342impl_from_clone_for_value!(String, Text);
343
344macro_rules! impl_from_array_for_value {
353 ( $( $t:ty) * ) => {
354 $(
355 impl From<Vec<$t>> for Value {
356 fn from(value: Vec<$t>) -> Self {
357 Self::Array(value.iter().map(|v| Value::from(v)).collect())
358 }
359 }
360 )*
361 };
362}
363impl_from_array_for_value!(bool i16 i32 i64 u16 u32 u64 f32 f64 String chrono::NaiveDateTime);
364
365