1use std::convert;
16use std::fmt;
17use std::mem;
18use std::net::Ipv4Addr;
19use std::net::Ipv6Addr;
20use std::str;
21use std::sync::Arc;
22
23use chrono::prelude::*;
24use chrono_tz::Tz;
25use uuid::Uuid;
26
27use crate::types::column::datetime64::to_datetime;
28use crate::types::column::Either;
29use crate::types::decimal::Decimal;
30use crate::types::decimal::NoBits;
31use crate::types::DateConverter;
32use crate::types::DateTimeType;
33use crate::types::Enum16;
34use crate::types::Enum8;
35use crate::types::HasSqlType;
36use crate::types::SqlType;
37use crate::types::UNIX_EPOCH_DAY;
38
39pub(crate) type AppDateTime = DateTime<Tz>;
40pub(crate) type AppDate = NaiveDate;
41
42#[derive(Clone, Debug)]
44pub enum Value {
45 UInt8(u8),
46 UInt16(u16),
47 UInt32(u32),
48 UInt64(u64),
49 Int8(i8),
50 Int16(i16),
51 Int32(i32),
52 Int64(i64),
53 String(Arc<Vec<u8>>),
54 Float32(f32),
55 Float64(f64),
56 Date(u16),
57 DateTime(u32, Tz),
58 DateTime64(i64, (u32, Tz)),
59 Ipv4([u8; 4]),
60 Ipv6([u8; 16]),
61 Uuid([u8; 16]),
62 Nullable(Either<&'static SqlType, Box<Value>>),
63 Array(&'static SqlType, Arc<Vec<Value>>),
64 Decimal(Decimal),
65 Enum8(Vec<(String, i8)>, Enum8),
66 Enum16(Vec<(String, i16)>, Enum16),
67 Tuple(Arc<Vec<Value>>),
68}
69
70impl PartialEq for Value {
71 fn eq(&self, other: &Self) -> bool {
72 match (self, other) {
73 (Value::UInt8(a), Value::UInt8(b)) => *a == *b,
74 (Value::UInt16(a), Value::UInt16(b)) => *a == *b,
75 (Value::UInt32(a), Value::UInt32(b)) => *a == *b,
76 (Value::UInt64(a), Value::UInt64(b)) => *a == *b,
77 (Value::Int8(a), Value::Int8(b)) => *a == *b,
78 (Value::Int16(a), Value::Int16(b)) => *a == *b,
79 (Value::Int32(a), Value::Int32(b)) => *a == *b,
80 (Value::Int64(a), Value::Int64(b)) => *a == *b,
81 (Value::String(a), Value::String(b)) => *a == *b,
82 (Value::Float32(a), Value::Float32(b)) => *a == *b,
83 (Value::Float64(a), Value::Float64(b)) => *a == *b,
84 (Value::Date(a), Value::Date(b)) => *a == *b,
85 (Value::DateTime(a, tz_a), Value::DateTime(b, tz_b)) => {
86 let time_a = tz_a.timestamp_opt(i64::from(*a), 0).unwrap();
87 let time_b = tz_b.timestamp_opt(i64::from(*b), 0).unwrap();
88 time_a == time_b
89 }
90 (Value::Nullable(a), Value::Nullable(b)) => *a == *b,
91 (Value::Array(ta, a), Value::Array(tb, b)) => *ta == *tb && *a == *b,
92 (Value::Decimal(a), Value::Decimal(b)) => *a == *b,
93 (Value::Enum16(values_a, val_a), Value::Enum16(values_b, val_b)) => {
94 *values_a == *values_b && *val_a == *val_b
95 }
96 (Value::Tuple(a), Value::Tuple(b)) => *a == *b,
97 _ => false,
98 }
99 }
100}
101
102impl Value {
103 pub fn default(sql_type: SqlType) -> Value {
104 match sql_type {
105 SqlType::UInt8 => Value::UInt8(0),
106 SqlType::UInt16 => Value::UInt16(0),
107 SqlType::UInt32 => Value::UInt32(0),
108 SqlType::UInt64 => Value::UInt64(0),
109 SqlType::Int8 => Value::Int8(0),
110 SqlType::Int16 => Value::Int16(0),
111 SqlType::Int32 => Value::Int32(0),
112 SqlType::Int64 => Value::Int64(0),
113 SqlType::String => Value::String(Arc::new(Vec::default())),
114 SqlType::FixedString(str_len) => Value::String(Arc::new(vec![0_u8; str_len])),
115 SqlType::Float32 => Value::Float32(0.0),
116 SqlType::Float64 => Value::Float64(0.0),
117 SqlType::Date => 0_u16.to_date(Tz::Zulu).into(),
118 SqlType::DateTime(DateTimeType::DateTime64(_, _)) => {
119 Value::DateTime64(0, (1, Tz::Zulu))
120 }
121 SqlType::DateTime(_) => 0_u32.to_date(Tz::Zulu).into(),
122 SqlType::Nullable(inner) => Value::Nullable(Either::Left(inner)),
123 SqlType::Array(inner) => Value::Array(inner, Arc::new(Vec::default())),
124 SqlType::Decimal(precision, scale) => Value::Decimal(Decimal {
125 underlying: 0,
126 precision,
127 scale,
128 nobits: NoBits::N64,
129 }),
130 SqlType::Ipv4 => Value::Ipv4([0_u8; 4]),
131 SqlType::Ipv6 => Value::Ipv6([0_u8; 16]),
132 SqlType::Uuid => Value::Uuid([0_u8; 16]),
133 SqlType::Enum8(values) => Value::Enum8(values, Enum8(0)),
134 SqlType::Enum16(values) => Value::Enum16(values, Enum16(0)),
135 SqlType::Tuple(types) => Value::Tuple(Arc::new(
136 types
137 .into_iter()
138 .map(|t| Value::default(t.clone()))
139 .collect(),
140 )),
141 }
142 }
143}
144
145impl fmt::Display for Value {
146 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
147 match self {
148 Value::UInt8(ref v) => fmt::Display::fmt(v, f),
149 Value::UInt16(ref v) => fmt::Display::fmt(v, f),
150 Value::UInt32(ref v) => fmt::Display::fmt(v, f),
151 Value::UInt64(ref v) => fmt::Display::fmt(v, f),
152 Value::Int8(ref v) => fmt::Display::fmt(v, f),
153 Value::Int16(ref v) => fmt::Display::fmt(v, f),
154 Value::Int32(ref v) => fmt::Display::fmt(v, f),
155 Value::Int64(ref v) => fmt::Display::fmt(v, f),
156 Value::String(ref v) => match str::from_utf8(v) {
157 Ok(s) => fmt::Display::fmt(s, f),
158 Err(_) => write!(f, "{:?}", v),
159 },
160 Value::Float32(ref v) => fmt::Display::fmt(v, f),
161 Value::Float64(ref v) => fmt::Display::fmt(v, f),
162 Value::DateTime(u, tz) if f.alternate() => {
163 let time = tz.timestamp_opt(i64::from(*u), 0).unwrap();
164 fmt::Display::fmt(&time, f)
165 }
166 Value::DateTime(u, tz) => {
167 let time = tz.timestamp_opt(i64::from(*u), 0).unwrap();
168 write!(f, "{}", time.to_rfc2822())
169 }
170 Value::DateTime64(value, params) => {
171 let (precision, tz) = params;
172 let time = to_datetime(*value, *precision, *tz);
173 write!(f, "{}", time.to_rfc2822())
174 }
175 Value::Date(v) if f.alternate() => {
176 let date =
177 NaiveDate::from_num_days_from_ce_opt((*v as i64 + UNIX_EPOCH_DAY) as i32)
178 .unwrap();
179 fmt::Display::fmt(&date, f)
180 }
181 Value::Date(v) => {
182 let date =
183 NaiveDate::from_num_days_from_ce_opt((*v as i64 + UNIX_EPOCH_DAY) as i32)
184 .unwrap();
185 fmt::Display::fmt(&date.format("%Y-%m-%d"), f)
186 }
187 Value::Nullable(v) => match v {
188 Either::Left(_) => write!(f, "NULL"),
189 Either::Right(data) => data.fmt(f),
190 },
191 Value::Array(_, vs) => {
192 let cells: Vec<String> = vs.iter().map(|v| format!("{}", v)).collect();
193 write!(f, "[{}]", cells.join(", "))
194 }
195 Value::Decimal(v) => fmt::Display::fmt(v, f),
196 Value::Ipv4(v) => {
197 write!(f, "{}", decode_ipv4(v))
198 }
199 Value::Ipv6(v) => {
200 write!(f, "{}", decode_ipv6(v))
201 }
202 Value::Uuid(v) => {
203 let mut buffer = *v;
204 buffer[..8].reverse();
205 buffer[8..].reverse();
206 match Uuid::from_slice(&buffer) {
207 Ok(uuid) => write!(f, "{}", uuid),
208 Err(e) => write!(f, "{}", e),
209 }
210 }
211 Value::Enum8(ref _v1, ref v2) => write!(f, "Enum8, {}", v2),
212 Value::Enum16(ref _v1, ref v2) => write!(f, "Enum16, {}", v2),
213 Value::Tuple(v) => {
214 let cells: Vec<String> = v.iter().map(|v| format!("{}", v)).collect();
215 write!(f, "({})", cells.join(", "))
216 }
217 }
218 }
219}
220
221impl convert::From<Value> for SqlType {
222 fn from(source: Value) -> Self {
223 match source {
224 Value::UInt8(_) => SqlType::UInt8,
225 Value::UInt16(_) => SqlType::UInt16,
226 Value::UInt32(_) => SqlType::UInt32,
227 Value::UInt64(_) => SqlType::UInt64,
228 Value::Int8(_) => SqlType::Int8,
229 Value::Int16(_) => SqlType::Int16,
230 Value::Int32(_) => SqlType::Int32,
231 Value::Int64(_) => SqlType::Int64,
232 Value::String(_) => SqlType::String,
233 Value::Float32(_) => SqlType::Float32,
234 Value::Float64(_) => SqlType::Float64,
235 Value::Date(_) => SqlType::Date,
236 Value::DateTime(_, _) => SqlType::DateTime(DateTimeType::DateTime32),
237 Value::Nullable(d) => match d {
238 Either::Left(t) => SqlType::Nullable(t),
239 Either::Right(inner) => {
240 let sql_type = SqlType::from(inner.as_ref().to_owned());
241 SqlType::Nullable(sql_type.into())
242 }
243 },
244 Value::Array(t, _) => SqlType::Array(t),
245 Value::Decimal(v) => SqlType::Decimal(v.precision, v.scale),
246 Value::Ipv4(_) => SqlType::Ipv4,
247 Value::Ipv6(_) => SqlType::Ipv6,
248 Value::Uuid(_) => SqlType::Uuid,
249 Value::Enum8(values, _) => SqlType::Enum8(values),
250 Value::Enum16(values, _) => SqlType::Enum16(values),
251 Value::DateTime64(_, params) => {
252 let (precision, tz) = params;
253 SqlType::DateTime(DateTimeType::DateTime64(precision, tz))
254 }
255 Value::Tuple(values) => {
256 let types: Vec<&'static SqlType> = values
257 .iter()
258 .map(|v| SqlType::from(v.to_owned()).into())
259 .collect();
260 SqlType::Tuple(types)
261 }
262 }
263 }
264}
265
266impl<T> convert::From<Option<T>> for Value
267where
268 Value: convert::From<T>,
269 T: HasSqlType,
270{
271 fn from(value: Option<T>) -> Value {
272 match value {
273 None => {
274 let default_type: SqlType = T::get_sql_type();
275 Value::Nullable(Either::Left(default_type.into()))
276 }
277 Some(inner) => Value::Nullable(Either::Right(Box::new(inner.into()))),
278 }
279 }
280}
281
282macro_rules! value_from {
283 ( $( $t:ty : $k:ident ),* ) => {
284 $(
285 impl convert::From<$t> for Value {
286 fn from(v: $t) -> Value {
287 Value::$k(v.into())
288 }
289 }
290 )*
291 };
292}
293
294impl convert::From<AppDate> for Value {
295 fn from(v: AppDate) -> Value {
296 Value::Date(u16::get_days(v))
297 }
298}
299
300impl convert::From<Enum8> for Value {
301 fn from(v: Enum8) -> Value {
302 Value::Enum8(vec![], v)
303 }
304}
305
306impl convert::From<Enum16> for Value {
307 fn from(v: Enum16) -> Value {
308 Value::Enum16(vec![], v)
309 }
310}
311
312impl convert::From<AppDateTime> for Value {
313 fn from(v: AppDateTime) -> Value {
314 Value::DateTime(v.timestamp() as u32, v.timezone())
315 }
316}
317
318impl convert::From<String> for Value {
319 fn from(v: String) -> Value {
320 Value::String(Arc::new(v.into_bytes()))
321 }
322}
323
324impl convert::From<Vec<u8>> for Value {
325 fn from(v: Vec<u8>) -> Value {
326 Value::String(Arc::new(v))
327 }
328}
329
330impl convert::From<&[u8]> for Value {
331 fn from(v: &[u8]) -> Value {
332 Value::String(Arc::new(v.to_vec()))
333 }
334}
335
336value_from! {
337 u8: UInt8,
338 u16: UInt16,
339 u32: UInt32,
340 u64: UInt64,
341
342 i8: Int8,
343 i16: Int16,
344 i32: Int32,
345 i64: Int64,
346
347 f32: Float32,
348 f64: Float64,
349
350 Decimal: Decimal
351}
352
353impl<'a> convert::From<&'a str> for Value {
354 fn from(v: &'a str) -> Self {
355 let bytes: Vec<u8> = v.as_bytes().into();
356 Value::String(Arc::new(bytes))
357 }
358}
359
360impl convert::From<Value> for String {
361 fn from(mut v: Value) -> Self {
362 if let Value::String(ref mut x) = &mut v {
363 let mut tmp = Arc::new(Vec::new());
364 mem::swap(x, &mut tmp);
365 if let Ok(result) = str::from_utf8(tmp.as_ref()) {
366 return result.into();
367 }
368 }
369 let from = SqlType::from(v);
370 panic!("Can't convert Value::{} into String.", from);
371 }
372}
373
374impl convert::From<Value> for Vec<u8> {
375 fn from(v: Value) -> Self {
376 match v {
377 Value::String(bs) => bs.to_vec(),
378 _ => {
379 let from = SqlType::from(v);
380 panic!("Can't convert Value::{} into Vec<u8>.", from)
381 }
382 }
383 }
384}
385
386macro_rules! from_value {
387 ( $( $t:ty : $k:ident ),* ) => {
388 $(
389 impl convert::From<Value> for $t {
390 fn from(v: Value) -> $t {
391 if let Value::$k(x) = v {
392 return x;
393 }
394 let from = SqlType::from(v);
395 panic!("Can't convert Value::{} into {}", from, stringify!($t))
396 }
397 }
398 )*
399 };
400}
401
402impl convert::From<Value> for AppDate {
403 fn from(v: Value) -> AppDate {
404 if let Value::Date(x) = v {
405 let date =
406 NaiveDate::from_num_days_from_ce_opt((x as i64 + UNIX_EPOCH_DAY) as i32).unwrap();
407 return date;
408 }
409 let from = SqlType::from(v);
410 panic!("Can't convert Value::{} into {}", from, "AppDate")
411 }
412}
413
414impl convert::From<Value> for AppDateTime {
415 fn from(v: Value) -> AppDateTime {
416 match v {
417 Value::DateTime(u, tz) => tz.timestamp_opt(i64::from(u), 0).unwrap(),
418 Value::DateTime64(u, params) => {
419 let (precision, tz) = params;
420 to_datetime(u, precision, tz)
421 }
422 _ => {
423 let from = SqlType::from(v);
424 panic!("Can't convert Value::{} into {}", from, "DateTime<Tz>")
425 }
426 }
427 }
428}
429
430from_value! {
431 u8: UInt8,
432 u16: UInt16,
433 u32: UInt32,
434 u64: UInt64,
435 i8: Int8,
436 i16: Int16,
437 i32: Int32,
438 i64: Int64,
439 f32: Float32,
440 f64: Float64
441}
442
443pub(crate) fn decode_ipv4(octets: &[u8; 4]) -> Ipv4Addr {
444 let mut buffer = *octets;
445 buffer.reverse();
446 Ipv4Addr::from(buffer)
447}
448
449pub(crate) fn decode_ipv6(octets: &[u8; 16]) -> Ipv6Addr {
450 Ipv6Addr::from(*octets)
451}