1use std::convert;
2use std::fmt;
3use std::str;
4use std::sync::Arc;
5
6use chrono::prelude::*;
7use chrono_tz::Tz;
8use uuid::Uuid;
9
10use crate::errors::Error;
11use crate::errors::FromSqlError;
12use crate::errors::Result;
13use crate::types::column::datetime64::to_datetime;
14use crate::types::column::Either;
15use crate::types::decimal::Decimal;
16use crate::types::value::decode_ipv4;
17use crate::types::value::decode_ipv6;
18use crate::types::value::AppDate;
19use crate::types::value::AppDateTime;
20use crate::types::DateTimeType;
21use crate::types::Enum16;
22use crate::types::Enum8;
23use crate::types::SqlType;
24use crate::types::Value;
25
26#[derive(Clone, Debug)]
27pub enum ValueRef<'a> {
28 UInt8(u8),
29 UInt16(u16),
30 UInt32(u32),
31 UInt64(u64),
32 Int8(i8),
33 Int16(i16),
34 Int32(i32),
35 Int64(i64),
36 String(&'a [u8]),
37 Float32(f32),
38 Float64(f64),
39 Date(u16, Tz),
40 DateTime(u32, Tz),
41 DateTime64(i64, &'a (u32, Tz)),
42 Nullable(Either<&'static SqlType, Box<ValueRef<'a>>>),
43 Array(&'static SqlType, Arc<Vec<ValueRef<'a>>>),
44 Decimal(Decimal),
45 Ipv4([u8; 4]),
46 Ipv6([u8; 16]),
47 Uuid([u8; 16]),
48 Enum16(Vec<(String, i16)>, Enum16),
49 Enum8(Vec<(String, i8)>, Enum8)
50}
51
52impl<'a> PartialEq for ValueRef<'a> {
53 fn eq(&self, other: &Self) -> bool {
54 match (self, other) {
55 (ValueRef::UInt8(a), ValueRef::UInt8(b)) => *a == *b,
56 (ValueRef::UInt16(a), ValueRef::UInt16(b)) => *a == *b,
57 (ValueRef::UInt32(a), ValueRef::UInt32(b)) => *a == *b,
58 (ValueRef::UInt64(a), ValueRef::UInt64(b)) => *a == *b,
59 (ValueRef::Int8(a), ValueRef::Int8(b)) => *a == *b,
60 (ValueRef::Int16(a), ValueRef::Int16(b)) => *a == *b,
61 (ValueRef::Int32(a), ValueRef::Int32(b)) => *a == *b,
62 (ValueRef::Int64(a), ValueRef::Int64(b)) => *a == *b,
63 (ValueRef::String(a), ValueRef::String(b)) => *a == *b,
64 (ValueRef::Float32(a), ValueRef::Float32(b)) => *a == *b,
65 (ValueRef::Float64(a), ValueRef::Float64(b)) => *a == *b,
66 (ValueRef::Date(a, tz_a), ValueRef::Date(b, tz_b)) => {
67 let time_a = tz_a.timestamp(i64::from(*a) * 24 * 3600, 0);
68 let time_b = tz_b.timestamp(i64::from(*b) * 24 * 3600, 0);
69 time_a.date() == time_b.date()
70 }
71 (ValueRef::DateTime(a, tz_a), ValueRef::DateTime(b, tz_b)) => {
72 let time_a = tz_a.timestamp(i64::from(*a), 0);
73 let time_b = tz_b.timestamp(i64::from(*b), 0);
74 time_a == time_b
75 }
76 (ValueRef::Nullable(a), ValueRef::Nullable(b)) => *a == *b,
77 (ValueRef::Array(ta, a), ValueRef::Array(tb, b)) => *ta == *tb && *a == *b,
78 (ValueRef::Decimal(a), ValueRef::Decimal(b)) => *a == *b,
79 (ValueRef::Enum8(a0, a1), ValueRef::Enum8(b0, b1)) => *a1 == *b1 && *a0 == *b0,
80 (ValueRef::Enum16(a0, a1), ValueRef::Enum16(b0, b1)) => *a1 == *b1 && *a0 == *b0,
81 (ValueRef::DateTime64(this, this_params), ValueRef::DateTime64(that, that_params)) => {
82 let (this_precision, this_tz) = **this_params;
83 let (that_precision2, that_tz) = **that_params;
84
85 let this_time = to_datetime(*this, this_precision, this_tz);
86 let that_time = to_datetime(*that, that_precision2, that_tz);
87
88 this_time == that_time
89 }
90 _ => false
91 }
92 }
93}
94
95impl<'a> fmt::Display for ValueRef<'a> {
96 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
97 match self {
98 ValueRef::UInt8(v) => fmt::Display::fmt(v, f),
99 ValueRef::UInt16(v) => fmt::Display::fmt(v, f),
100 ValueRef::UInt32(v) => fmt::Display::fmt(v, f),
101 ValueRef::UInt64(v) => fmt::Display::fmt(v, f),
102 ValueRef::Int8(v) => fmt::Display::fmt(v, f),
103 ValueRef::Int16(v) => fmt::Display::fmt(v, f),
104 ValueRef::Int32(v) => fmt::Display::fmt(v, f),
105 ValueRef::Int64(v) => fmt::Display::fmt(v, f),
106 ValueRef::String(v) => match str::from_utf8(v) {
107 Ok(s) => fmt::Display::fmt(s, f),
108 Err(_) => write!(f, "{:?}", *v)
109 },
110 ValueRef::Float32(v) => fmt::Display::fmt(v, f),
111 ValueRef::Float64(v) => fmt::Display::fmt(v, f),
112 ValueRef::Date(v, tz) if f.alternate() => {
113 let time = tz.timestamp(i64::from(*v) * 24 * 3600, 0);
114 let date = time.date();
115 fmt::Display::fmt(&date, f)
116 }
117 ValueRef::Date(v, tz) => {
118 let time = tz.timestamp(i64::from(*v) * 24 * 3600, 0);
119 let date = time.date();
120 fmt::Display::fmt(&date.format("%Y-%m-%d"), f)
121 }
122 ValueRef::DateTime(u, tz) if f.alternate() => {
123 let time = tz.timestamp(i64::from(*u), 0);
124 write!(f, "{}", time.to_rfc2822())
125 }
126 ValueRef::DateTime(u, tz) => {
127 let time = tz.timestamp(i64::from(*u), 0);
128 fmt::Display::fmt(&time.format("%Y-%m-%d %H:%M:%S"), f)
129 }
130 ValueRef::DateTime64(u, params) => {
131 let (precision, tz) = **params;
132 let time = to_datetime(*u, precision, tz);
133 fmt::Display::fmt(&time.format("%Y-%m-%d %H:%M:%S"), f)
134 }
135 ValueRef::Nullable(v) => match v {
136 Either::Left(_) => write!(f, "NULL"),
137 Either::Right(inner) => write!(f, "{}", inner)
138 },
139 ValueRef::Array(_, vs) => {
140 let cells: Vec<String> = vs.iter().map(|v| format!("{}", v)).collect();
141 write!(f, "[{}]", cells.join(", "))
142 }
143 ValueRef::Decimal(v) => fmt::Display::fmt(v, f),
144 ValueRef::Ipv4(v) => {
145 write!(f, "{}", decode_ipv4(v))
146 }
147 ValueRef::Ipv6(v) => {
148 write!(f, "{}", decode_ipv6(v))
149 }
150 ValueRef::Uuid(v) => {
151 let mut buffer = *v;
152 buffer[..8].reverse();
153 buffer[8..].reverse();
154 match Uuid::from_slice(&buffer) {
155 Ok(uuid) => write!(f, "{}", uuid),
156 Err(e) => write!(f, "{}", e)
157 }
158 }
159 ValueRef::Enum8(_, v) => fmt::Display::fmt(v, f),
160 ValueRef::Enum16(_, v) => fmt::Display::fmt(v, f)
161 }
162 }
163}
164
165impl<'a> convert::From<ValueRef<'a>> for SqlType {
166 fn from(source: ValueRef<'a>) -> Self {
167 match source {
168 ValueRef::UInt8(_) => SqlType::UInt8,
169 ValueRef::UInt16(_) => SqlType::UInt16,
170 ValueRef::UInt32(_) => SqlType::UInt32,
171 ValueRef::UInt64(_) => SqlType::UInt64,
172 ValueRef::Int8(_) => SqlType::Int8,
173 ValueRef::Int16(_) => SqlType::Int16,
174 ValueRef::Int32(_) => SqlType::Int32,
175 ValueRef::Int64(_) => SqlType::Int64,
176 ValueRef::String(_) => SqlType::String,
177 ValueRef::Float32(_) => SqlType::Float32,
178 ValueRef::Float64(_) => SqlType::Float64,
179 ValueRef::Date(_, _) => SqlType::Date,
180 ValueRef::DateTime(_, _) => SqlType::DateTime(DateTimeType::DateTime32),
181 ValueRef::Nullable(u) => match u {
182 Either::Left(sql_type) => SqlType::Nullable(sql_type),
183 Either::Right(value_ref) => SqlType::Nullable(SqlType::from(*value_ref).into())
184 },
185 ValueRef::Array(t, _) => SqlType::Array(t),
186 ValueRef::Decimal(v) => SqlType::Decimal(v.precision, v.scale),
187 ValueRef::Enum8(values, _) => SqlType::Enum8(values),
188 ValueRef::Enum16(values, _) => SqlType::Enum16(values),
189 ValueRef::Ipv4(_) => SqlType::Ipv4,
190 ValueRef::Ipv6(_) => SqlType::Ipv6,
191 ValueRef::Uuid(_) => SqlType::Uuid,
192 ValueRef::DateTime64(_, params) => {
193 let (precision, tz) = params;
194 SqlType::DateTime(DateTimeType::DateTime64(*precision, *tz))
195 }
196 }
197 }
198}
199
200impl<'a> ValueRef<'a> {
201 pub fn as_str(&self) -> Result<&'a str> {
202 if let ValueRef::String(t) = self {
203 return Ok(str::from_utf8(t)?);
204 }
205 let from = SqlType::from(self.clone()).to_string();
206 Err(Error::FromSql(FromSqlError::InvalidType {
207 src: from,
208 dst: "&str".into()
209 }))
210 }
211
212 pub fn as_string(&self) -> Result<String> {
213 let tmp = self.as_str()?;
214 Ok(tmp.to_string())
215 }
216
217 pub fn as_bytes(&self) -> Result<&'a [u8]> {
218 if let ValueRef::String(t) = self {
219 return Ok(t);
220 }
221 let from = SqlType::from(self.clone()).to_string();
222 Err(Error::FromSql(FromSqlError::InvalidType {
223 src: from,
224 dst: "&[u8]".into()
225 }))
226 }
227}
228
229impl<'a> From<ValueRef<'a>> for Value {
230 fn from(borrowed: ValueRef<'a>) -> Self {
231 match borrowed {
232 ValueRef::UInt8(v) => Value::UInt8(v),
233 ValueRef::UInt16(v) => Value::UInt16(v),
234 ValueRef::UInt32(v) => Value::UInt32(v),
235 ValueRef::UInt64(v) => Value::UInt64(v),
236 ValueRef::Int8(v) => Value::Int8(v),
237 ValueRef::Int16(v) => Value::Int16(v),
238 ValueRef::Int32(v) => Value::Int32(v),
239 ValueRef::Int64(v) => Value::Int64(v),
240 ValueRef::String(v) => Value::String(Arc::new(v.into())),
241 ValueRef::Float32(v) => Value::Float32(v),
242 ValueRef::Float64(v) => Value::Float64(v),
243 ValueRef::Date(v, tz) => Value::Date(v, tz),
244 ValueRef::DateTime(v, tz) => Value::DateTime(v, tz),
245 ValueRef::Nullable(u) => match u {
246 Either::Left(sql_type) => Value::Nullable(Either::Left((sql_type.clone()).into())),
247 Either::Right(v) => {
248 let value: Value = (*v).into();
249 Value::Nullable(Either::Right(Box::new(value)))
250 }
251 },
252 ValueRef::Array(t, vs) => {
253 let mut value_list: Vec<Value> = Vec::with_capacity(vs.len());
254 for v in vs.iter() {
255 let value: Value = v.clone().into();
256 value_list.push(value);
257 }
258 Value::Array(t, Arc::new(value_list))
259 }
260 ValueRef::Decimal(v) => Value::Decimal(v),
261 ValueRef::Enum8(e_v, v) => Value::Enum8(e_v, v),
262 ValueRef::Enum16(e_v, v) => Value::Enum16(e_v, v),
263 ValueRef::Ipv4(v) => Value::Ipv4(v),
264 ValueRef::Ipv6(v) => Value::Ipv6(v),
265 ValueRef::Uuid(v) => Value::Uuid(v),
266 ValueRef::DateTime64(v, params) => Value::DateTime64(v, *params)
267 }
268 }
269}
270
271impl<'a> From<&'a str> for ValueRef<'a> {
272 fn from(s: &str) -> ValueRef {
273 ValueRef::String(s.as_bytes())
274 }
275}
276
277impl<'a> From<&'a [u8]> for ValueRef<'a> {
278 fn from(bs: &[u8]) -> ValueRef {
279 ValueRef::String(bs)
280 }
281}
282
283macro_rules! from_number {
284 ( $($t:ty: $k:ident),* ) => {
285 $(
286 impl<'a> From<$t> for ValueRef<'a> {
287 fn from(v: $t) -> ValueRef<'static> {
288 ValueRef::$k(v)
289 }
290 }
291 )*
292 };
293}
294
295from_number! {
296 u8: UInt8,
297 u16: UInt16,
298 u32: UInt32,
299 u64: UInt64,
300
301 i8: Int8,
302 i16: Int16,
303 i32: Int32,
304 i64: Int64,
305
306 f32: Float32,
307 f64: Float64
308}
309
310impl<'a> From<&'a Value> for ValueRef<'a> {
311 fn from(value: &'a Value) -> ValueRef<'a> {
312 match value {
313 Value::UInt8(v) => ValueRef::UInt8(*v),
314 Value::UInt16(v) => ValueRef::UInt16(*v),
315 Value::UInt32(v) => ValueRef::UInt32(*v),
316 Value::UInt64(v) => ValueRef::UInt64(*v),
317 Value::Int8(v) => ValueRef::Int8(*v),
318 Value::Int16(v) => ValueRef::Int16(*v),
319 Value::Int32(v) => ValueRef::Int32(*v),
320 Value::Int64(v) => ValueRef::Int64(*v),
321 Value::String(v) => ValueRef::String(v),
322 Value::Float32(v) => ValueRef::Float32(*v),
323 Value::Float64(v) => ValueRef::Float64(*v),
324 Value::Date(v, tz) => ValueRef::Date(*v, *tz),
325 Value::DateTime(v, tz) => ValueRef::DateTime(*v, *tz),
326 Value::DateTime64(v, params) => ValueRef::DateTime64(*v, params),
327 Value::Nullable(u) => match u {
328 Either::Left(sql_type) => ValueRef::Nullable(Either::Left(sql_type.to_owned())),
329 Either::Right(v) => {
330 let value_ref = v.as_ref().into();
331 ValueRef::Nullable(Either::Right(Box::new(value_ref)))
332 }
333 },
334 Value::Array(t, vs) => {
335 let mut ref_vec = Vec::with_capacity(vs.len());
336 for v in vs.iter() {
337 let value_ref: ValueRef<'a> = From::from(v);
338 ref_vec.push(value_ref)
339 }
340 ValueRef::Array(*t, Arc::new(ref_vec))
341 }
342 Value::Decimal(v) => ValueRef::Decimal(v.clone()),
343 Value::Enum8(values, v) => ValueRef::Enum8(values.to_vec(), *v),
344 Value::Enum16(values, v) => ValueRef::Enum16(values.to_vec(), *v),
345 Value::Ipv4(v) => ValueRef::Ipv4(*v),
346 Value::Ipv6(v) => ValueRef::Ipv6(*v),
347 Value::Uuid(v) => ValueRef::Uuid(*v)
348 }
349 }
350}
351
352macro_rules! value_from {
353 ( $( $t:ty: $k:ident ),* ) => {
354 $(
355 impl<'a> From<ValueRef<'a>> for $t {
356 fn from(value: ValueRef<'a>) -> Self {
357 if let ValueRef::$k(v) = value {
358 return v
359 }
360 let from = format!("{}", SqlType::from(value.clone()));
361 panic!("Can't convert ValueRef::{} into {}.",
362 from, stringify!($t))
363 }
364 }
365 )*
366 };
367}
368
369impl<'a> From<ValueRef<'a>> for AppDate {
370 fn from(value: ValueRef<'a>) -> Self {
371 if let ValueRef::Date(v, tz) = value {
372 let time = tz.timestamp(i64::from(v) * 24 * 3600, 0);
373 return time.date();
374 }
375 let from = format!("{}", SqlType::from(value.clone()));
376 panic!("Can't convert ValueRef::{} into {}.", from, stringify!($t))
377 }
378}
379
380impl<'a> From<ValueRef<'a>> for AppDateTime {
381 fn from(value: ValueRef<'a>) -> Self {
382 match value {
383 ValueRef::DateTime(x, tz) => tz.timestamp(i64::from(x), 0),
384 ValueRef::DateTime64(x, params) => {
385 let (precision, tz) = *params;
386 to_datetime(x, precision, tz)
387 }
388 _ => {
389 let from = format!("{}", SqlType::from(value.clone()));
390 panic!("Can't convert ValueRef::{} into {}.", from, "DateTime<Tz>")
391 }
392 }
393 }
394}
395
396value_from! {
397 u8: UInt8,
398 u16: UInt16,
399 u32: UInt32,
400 u64: UInt64,
401
402 i8: Int8,
403 i16: Int16,
404 i32: Int32,
405 i64: Int64,
406
407 f32: Float32,
408 f64: Float64
409}
410
411#[cfg(test)]
412mod test {
413 use super::*;
414
415 #[test]
416 fn test_display() {
417 assert_eq!(
418 "[0, 159, 146, 150]".to_string(),
419 format!("{}", ValueRef::String(&[0, 159, 146, 150]))
420 );
421
422 assert_eq!("text".to_string(), format!("{}", ValueRef::String(b"text")));
423
424 assert_eq!("42".to_string(), format!("{}", ValueRef::UInt8(42)));
425 assert_eq!("42".to_string(), format!("{}", ValueRef::UInt16(42)));
426 assert_eq!("42".to_string(), format!("{}", ValueRef::UInt32(42)));
427 assert_eq!("42".to_string(), format!("{}", ValueRef::UInt64(42)));
428
429 assert_eq!("42".to_string(), format!("{}", ValueRef::Int8(42)));
430 assert_eq!("42".to_string(), format!("{}", ValueRef::Int16(42)));
431 assert_eq!("42".to_string(), format!("{}", ValueRef::Int32(42)));
432 assert_eq!("42".to_string(), format!("{}", ValueRef::Int64(42)));
433
434 assert_eq!("42".to_string(), format!("{}", ValueRef::Float32(42.0)));
435 assert_eq!("42".to_string(), format!("{}", ValueRef::Float64(42.0)));
436
437 assert_eq!(
438 "NULL".to_string(),
439 format!(
440 "{}",
441 ValueRef::Nullable(Either::Left(SqlType::UInt8.into()))
442 )
443 );
444
445 assert_eq!(
446 "42".to_string(),
447 format!(
448 "{}",
449 ValueRef::Nullable(Either::Right(Box::new(ValueRef::UInt8(42))))
450 )
451 );
452
453 assert_eq!(
454 "[1, 2, 3]".to_string(),
455 format!(
456 "{}",
457 ValueRef::Array(
458 SqlType::Int32.into(),
459 Arc::new(vec![
460 ValueRef::Int32(1),
461 ValueRef::Int32(2),
462 ValueRef::Int32(3)
463 ])
464 )
465 )
466 );
467
468 assert_eq!(
469 "1970-01-01".to_string(),
470 format!("{}", ValueRef::Date(0, Tz::Zulu))
471 );
472
473 assert_eq!(
474 "1970-01-01UTC".to_string(),
475 format!("{:#}", ValueRef::Date(0, Tz::Zulu))
476 );
477
478 assert_eq!(
479 "1970-01-01 00:00:00".to_string(),
480 format!("{}", ValueRef::DateTime(0, Tz::Zulu))
481 );
482
483 assert_eq!(
484 "Thu, 01 Jan 1970 00:00:00 +0000".to_string(),
485 format!("{:#}", ValueRef::DateTime(0, Tz::Zulu))
486 );
487
488 assert_eq!(
489 "2.00".to_string(),
490 format!("{}", ValueRef::Decimal(Decimal::of(2.0_f64, 2)))
491 )
492 }
493
494 #[test]
495 fn test_size_of() {
496 use std::mem;
497 assert_eq!(32, mem::size_of::<[ValueRef<'_>; 1]>());
498 }
499
500 #[test]
501 fn test_value_from_ref() {
502 assert_eq!(Value::from(ValueRef::UInt8(42)), Value::UInt8(42));
503 assert_eq!(Value::from(ValueRef::UInt16(42)), Value::UInt16(42));
504 assert_eq!(Value::from(ValueRef::UInt32(42)), Value::UInt32(42));
505 assert_eq!(Value::from(ValueRef::UInt64(42)), Value::UInt64(42));
506
507 assert_eq!(Value::from(ValueRef::Int8(42)), Value::Int8(42));
508 assert_eq!(Value::from(ValueRef::Int16(42)), Value::Int16(42));
509 assert_eq!(Value::from(ValueRef::Int32(42)), Value::Int32(42));
510 assert_eq!(Value::from(ValueRef::Int64(42)), Value::Int64(42));
511
512 assert_eq!(Value::from(ValueRef::Float32(42.0)), Value::Float32(42.0));
513 assert_eq!(Value::from(ValueRef::Float64(42.0)), Value::Float64(42.0));
514
515 assert_eq!(
516 Value::from(ValueRef::Date(42, Tz::Zulu)),
517 Value::Date(42, Tz::Zulu)
518 );
519 assert_eq!(
520 Value::from(ValueRef::DateTime(42, Tz::Zulu)),
521 Value::DateTime(42, Tz::Zulu)
522 );
523
524 assert_eq!(
525 Value::from(ValueRef::Decimal(Decimal::of(2.0_f64, 4))),
526 Value::Decimal(Decimal::of(2.0_f64, 4))
527 );
528
529 assert_eq!(
530 Value::from(ValueRef::Array(
531 SqlType::Int32.into(),
532 Arc::new(vec![
533 ValueRef::Int32(1),
534 ValueRef::Int32(2),
535 ValueRef::Int32(3)
536 ])
537 )),
538 Value::Array(
539 SqlType::Int32.into(),
540 Arc::new(vec![Value::Int32(1), Value::Int32(2), Value::Int32(3)])
541 )
542 )
543 }
544
545 #[test]
546 fn test_uuid() {
547 let uuid = Uuid::parse_str("936da01f-9abd-4d9d-80c7-02af85c822a8").unwrap();
548 let mut buffer = *uuid.as_bytes();
549 buffer[..8].reverse();
550 buffer[8..].reverse();
551 let v = ValueRef::Uuid(buffer);
552 assert_eq!(v.to_string(), "936da01f-9abd-4d9d-80c7-02af85c822a8");
553 }
554
555 #[test]
556 fn test_get_sql_type() {
557 assert_eq!(SqlType::from(ValueRef::UInt8(42)), SqlType::UInt8);
558 assert_eq!(SqlType::from(ValueRef::UInt16(42)), SqlType::UInt16);
559 assert_eq!(SqlType::from(ValueRef::UInt32(42)), SqlType::UInt32);
560 assert_eq!(SqlType::from(ValueRef::UInt64(42)), SqlType::UInt64);
561
562 assert_eq!(SqlType::from(ValueRef::Int8(42)), SqlType::Int8);
563 assert_eq!(SqlType::from(ValueRef::Int16(42)), SqlType::Int16);
564 assert_eq!(SqlType::from(ValueRef::Int32(42)), SqlType::Int32);
565 assert_eq!(SqlType::from(ValueRef::Int64(42)), SqlType::Int64);
566
567 assert_eq!(SqlType::from(ValueRef::Float32(42.0)), SqlType::Float32);
568 assert_eq!(SqlType::from(ValueRef::Float64(42.0)), SqlType::Float64);
569
570 assert_eq!(SqlType::from(ValueRef::String(&[])), SqlType::String);
571
572 assert_eq!(SqlType::from(ValueRef::Date(42, Tz::Zulu)), SqlType::Date);
573 assert_eq!(
574 SqlType::from(ValueRef::DateTime(42, Tz::Zulu)),
575 SqlType::DateTime(DateTimeType::DateTime32)
576 );
577
578 assert_eq!(
579 SqlType::from(ValueRef::Decimal(Decimal::of(2.0_f64, 4))),
580 SqlType::Decimal(18, 4)
581 );
582
583 assert_eq!(
584 SqlType::from(ValueRef::Array(
585 SqlType::Int32.into(),
586 Arc::new(vec![
587 ValueRef::Int32(1),
588 ValueRef::Int32(2),
589 ValueRef::Int32(3)
590 ])
591 )),
592 SqlType::Array(SqlType::Int32.into())
593 );
594
595 assert_eq!(
596 SqlType::from(ValueRef::Nullable(Either::Left(SqlType::UInt8.into()))),
597 SqlType::Nullable(SqlType::UInt8.into())
598 );
599
600 assert_eq!(
601 SqlType::from(ValueRef::Nullable(Either::Right(Box::new(ValueRef::Int8(
602 42
603 ))))),
604 SqlType::Nullable(SqlType::Int8.into())
605 );
606 }
607}