#![allow(private_bounds)]
use bigdecimal::BigDecimal;
use chrono::{DateTime, NaiveDate, NaiveDateTime, NaiveTime, Utc};
use num_bigint::BigInt;
use serde::{Deserialize, Serialize};
use qubit_common::lang::DataType;
use super::error::{ValueError, ValueResult};
use super::value::Value;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum MultiValues {
Empty(DataType),
Bool(Vec<bool>),
Char(Vec<char>),
Int8(Vec<i8>),
Int16(Vec<i16>),
Int32(Vec<i32>),
Int64(Vec<i64>),
Int128(Vec<i128>),
UInt8(Vec<u8>),
UInt16(Vec<u16>),
UInt32(Vec<u32>),
UInt64(Vec<u64>),
UInt128(Vec<u128>),
Float32(Vec<f32>),
Float64(Vec<f64>),
String(Vec<String>),
Date(Vec<NaiveDate>),
Time(Vec<NaiveTime>),
DateTime(Vec<NaiveDateTime>),
Instant(Vec<DateTime<Utc>>),
BigInteger(Vec<BigInt>),
BigDecimal(Vec<BigDecimal>),
}
macro_rules! impl_get_multi_values {
($(#[$attr:meta])* slice: $method:ident, $variant:ident, $type:ty, $data_type:expr) => {
$(#[$attr])*
pub fn $method(&self) -> ValueResult<&[$type]> {
match self {
MultiValues::$variant(v) => Ok(v),
MultiValues::Empty(_) => Ok(&[]),
_ => Err(ValueError::TypeMismatch {
expected: $data_type,
actual: self.data_type(),
}),
}
}
};
($(#[$attr:meta])* vec: $method:ident, $variant:ident, $type:ty, $data_type:expr) => {
$(#[$attr])*
pub fn $method(&self) -> ValueResult<&[$type]> {
match self {
MultiValues::$variant(v) => Ok(v.as_slice()),
MultiValues::Empty(_) => Ok(&[]),
_ => Err(ValueError::TypeMismatch {
expected: $data_type,
actual: self.data_type(),
}),
}
}
};
}
macro_rules! impl_get_first_value {
($(#[$attr:meta])* copy: $method:ident, $variant:ident, $type:ty, $data_type:expr) => {
$(#[$attr])*
pub fn $method(&self) -> ValueResult<$type> {
match self {
MultiValues::$variant(v) if !v.is_empty() => Ok(v[0]),
MultiValues::$variant(_) | MultiValues::Empty(_) => Err(ValueError::NoValue),
_ => Err(ValueError::TypeMismatch {
expected: $data_type,
actual: self.data_type(),
}),
}
}
};
($(#[$attr:meta])* ref: $method:ident, $variant:ident, $ret_type:ty, $data_type:expr, $conversion:expr) => {
$(#[$attr])*
pub fn $method(&self) -> ValueResult<$ret_type> {
match self {
MultiValues::$variant(v) if !v.is_empty() => {
let conv_fn: fn(&_) -> $ret_type = $conversion;
Ok(conv_fn(&v[0]))
},
MultiValues::$variant(_) | MultiValues::Empty(_) => Err(ValueError::NoValue),
_ => Err(ValueError::TypeMismatch {
expected: $data_type,
actual: self.data_type(),
}),
}
}
};
}
macro_rules! impl_add_single_value {
($(#[$attr:meta])* $method:ident, $variant:ident, $type:ty, $data_type:expr) => {
$(#[$attr])*
pub fn $method(&mut self, value: $type) -> ValueResult<()> {
match self {
MultiValues::$variant(v) => {
v.push(value);
Ok(())
}
MultiValues::Empty(dt) if *dt == $data_type => {
*self = MultiValues::$variant(vec![value]);
Ok(())
}
_ => Err(ValueError::TypeMismatch {
expected: $data_type,
actual: self.data_type(),
}),
}
}
};
}
macro_rules! impl_add_multi_values {
($(#[$attr:meta])* $method:ident, $variant:ident, $type:ty, $data_type:expr) => {
$(#[$attr])*
pub fn $method(&mut self, values: Vec<$type>) -> ValueResult<()> {
match self {
MultiValues::$variant(v) => {
v.extend(values);
Ok(())
}
MultiValues::Empty(dt) if *dt == $data_type => {
*self = MultiValues::$variant(values);
Ok(())
}
_ => Err(ValueError::TypeMismatch {
expected: $data_type,
actual: self.data_type(),
}),
}
}
};
}
macro_rules! impl_add_multi_values_slice {
($(#[$attr:meta])* $method:ident, $variant:ident, $type:ty, $data_type:expr) => {
$(#[$attr])*
pub fn $method(&mut self, values: &[$type]) -> ValueResult<()> {
match self {
MultiValues::$variant(v) => {
v.extend_from_slice(values);
Ok(())
}
MultiValues::Empty(dt) if *dt == $data_type => {
*self = MultiValues::$variant(values.to_vec());
Ok(())
}
_ => Err(ValueError::TypeMismatch {
expected: $data_type,
actual: self.data_type(),
}),
}
}
};
}
macro_rules! impl_set_single_value {
($(#[$attr:meta])* $method:ident, $variant:ident, $type:ty, $data_type:expr) => {
$(#[$attr])*
pub fn $method(&mut self, value: $type) -> ValueResult<()> {
*self = MultiValues::$variant(vec![value]);
Ok(())
}
};
}
macro_rules! impl_set_multi_values {
($(#[$attr:meta])* $method:ident, $variant:ident, $type:ty, $data_type:expr) => {
$(#[$attr])*
pub fn $method(&mut self, values: Vec<$type>) -> ValueResult<()> {
*self = MultiValues::$variant(values);
Ok(())
}
};
}
macro_rules! impl_set_multi_values_slice {
($(#[$attr:meta])* $method:ident, $variant:ident, $type:ty, $data_type:expr) => {
$(#[$attr])*
pub fn $method(&mut self, values: &[$type]) -> ValueResult<()> {
*self = MultiValues::$variant(values.to_vec());
Ok(())
}
};
}
impl MultiValues {
pub fn new<T>(values: Vec<T>) -> Self
where
Self: MultiValuesConstructor<T>,
{
<Self as MultiValuesConstructor<T>>::from_vec(values)
}
pub fn get<T>(&self) -> ValueResult<Vec<T>>
where
Self: MultiValuesGetter<T>,
{
<Self as MultiValuesGetter<T>>::get_values(self)
}
pub fn get_first<T>(&self) -> ValueResult<T>
where
Self: MultiValuesFirstGetter<T>,
{
<Self as MultiValuesFirstGetter<T>>::get_first_value(self)
}
pub fn set<'a, S>(&mut self, values: S) -> ValueResult<()>
where
S: MultiValuesSetArg<'a>,
Self: MultiValuesSetter<S::Item>
+ MultiValuesSetterSlice<S::Item>
+ MultiValuesSingleSetter<S::Item>,
{
values.apply(self)
}
pub fn add<'a, S>(&mut self, values: S) -> ValueResult<()>
where
S: MultiValuesAddArg<'a>,
Self: MultiValuesAdder<S::Item> + MultiValuesMultiAdder<S::Item>,
{
values.apply_add(self)
}
pub fn data_type(&self) -> DataType {
match self {
MultiValues::Empty(dt) => *dt,
MultiValues::Bool(_) => DataType::Bool,
MultiValues::Char(_) => DataType::Char,
MultiValues::Int8(_) => DataType::Int8,
MultiValues::Int16(_) => DataType::Int16,
MultiValues::Int32(_) => DataType::Int32,
MultiValues::Int64(_) => DataType::Int64,
MultiValues::Int128(_) => DataType::Int128,
MultiValues::UInt8(_) => DataType::UInt8,
MultiValues::UInt16(_) => DataType::UInt16,
MultiValues::UInt32(_) => DataType::UInt32,
MultiValues::UInt64(_) => DataType::UInt64,
MultiValues::UInt128(_) => DataType::UInt128,
MultiValues::Float32(_) => DataType::Float32,
MultiValues::Float64(_) => DataType::Float64,
MultiValues::String(_) => DataType::String,
MultiValues::Date(_) => DataType::Date,
MultiValues::Time(_) => DataType::Time,
MultiValues::DateTime(_) => DataType::DateTime,
MultiValues::Instant(_) => DataType::Instant,
MultiValues::BigInteger(_) => DataType::BigInteger,
MultiValues::BigDecimal(_) => DataType::BigDecimal,
}
}
pub fn count(&self) -> usize {
match self {
MultiValues::Empty(_) => 0,
MultiValues::Bool(v) => v.len(),
MultiValues::Char(v) => v.len(),
MultiValues::Int8(v) => v.len(),
MultiValues::Int16(v) => v.len(),
MultiValues::Int32(v) => v.len(),
MultiValues::Int64(v) => v.len(),
MultiValues::Int128(v) => v.len(),
MultiValues::UInt8(v) => v.len(),
MultiValues::UInt16(v) => v.len(),
MultiValues::UInt32(v) => v.len(),
MultiValues::UInt64(v) => v.len(),
MultiValues::UInt128(v) => v.len(),
MultiValues::Float32(v) => v.len(),
MultiValues::Float64(v) => v.len(),
MultiValues::String(v) => v.len(),
MultiValues::Date(v) => v.len(),
MultiValues::Time(v) => v.len(),
MultiValues::DateTime(v) => v.len(),
MultiValues::Instant(v) => v.len(),
MultiValues::BigInteger(v) => v.len(),
MultiValues::BigDecimal(v) => v.len(),
}
}
pub fn is_empty(&self) -> bool {
self.count() == 0
}
pub fn clear(&mut self) {
match self {
MultiValues::Empty(_) => {}
MultiValues::Bool(v) => v.clear(),
MultiValues::Char(v) => v.clear(),
MultiValues::Int8(v) => v.clear(),
MultiValues::Int16(v) => v.clear(),
MultiValues::Int32(v) => v.clear(),
MultiValues::Int64(v) => v.clear(),
MultiValues::Int128(v) => v.clear(),
MultiValues::UInt8(v) => v.clear(),
MultiValues::UInt16(v) => v.clear(),
MultiValues::UInt32(v) => v.clear(),
MultiValues::UInt64(v) => v.clear(),
MultiValues::UInt128(v) => v.clear(),
MultiValues::Float32(v) => v.clear(),
MultiValues::Float64(v) => v.clear(),
MultiValues::String(v) => v.clear(),
MultiValues::Date(v) => v.clear(),
MultiValues::Time(v) => v.clear(),
MultiValues::DateTime(v) => v.clear(),
MultiValues::Instant(v) => v.clear(),
MultiValues::BigInteger(v) => v.clear(),
MultiValues::BigDecimal(v) => v.clear(),
}
}
pub fn set_type(&mut self, data_type: DataType) {
if self.data_type() != data_type {
*self = MultiValues::Empty(data_type);
}
}
impl_get_first_value! {
copy: get_first_bool, Bool, bool, DataType::Bool
}
impl_get_first_value! {
copy: get_first_char, Char, char, DataType::Char
}
impl_get_first_value! {
copy: get_first_int8, Int8, i8, DataType::Int8
}
impl_get_first_value! {
copy: get_first_int16, Int16, i16, DataType::Int16
}
impl_get_first_value! {
copy: get_first_int32, Int32, i32, DataType::Int32
}
impl_get_first_value! {
copy: get_first_int64, Int64, i64, DataType::Int64
}
impl_get_first_value! {
copy: get_first_int128, Int128, i128, DataType::Int128
}
impl_get_first_value! {
copy: get_first_uint8, UInt8, u8, DataType::UInt8
}
impl_get_first_value! {
copy: get_first_uint16, UInt16, u16, DataType::UInt16
}
impl_get_first_value! {
copy: get_first_uint32, UInt32, u32, DataType::UInt32
}
impl_get_first_value! {
copy: get_first_uint64, UInt64, u64, DataType::UInt64
}
impl_get_first_value! {
copy: get_first_uint128, UInt128, u128, DataType::UInt128
}
impl_get_first_value! {
copy: get_first_float32, Float32, f32, DataType::Float32
}
impl_get_first_value! {
copy: get_first_float64, Float64, f64, DataType::Float64
}
impl_get_first_value! {
ref: get_first_string, String, &str, DataType::String, |s: &String| s.as_str()
}
impl_get_first_value! {
copy: get_first_date, Date, NaiveDate, DataType::Date
}
impl_get_first_value! {
copy: get_first_time, Time, NaiveTime, DataType::Time
}
impl_get_first_value! {
copy: get_first_datetime, DateTime, NaiveDateTime, DataType::DateTime
}
impl_get_first_value! {
copy: get_first_instant, Instant, DateTime<Utc>, DataType::Instant
}
impl_get_first_value! {
ref: get_first_biginteger, BigInteger, BigInt, DataType::BigInteger, |v: &BigInt| v.clone()
}
impl_get_first_value! {
ref: get_first_bigdecimal, BigDecimal, BigDecimal, DataType::BigDecimal, |v: &BigDecimal| v.clone()
}
impl_get_multi_values! {
slice: get_bools, Bool, bool, DataType::Bool
}
impl_get_multi_values! {
slice: get_chars, Char, char, DataType::Char
}
impl_get_multi_values! {
slice: get_int8s, Int8, i8, DataType::Int8
}
impl_get_multi_values! {
slice: get_int16s, Int16, i16, DataType::Int16
}
impl_get_multi_values! {
slice: get_int32s, Int32, i32, DataType::Int32
}
impl_get_multi_values! {
slice: get_int64s, Int64, i64, DataType::Int64
}
impl_get_multi_values! {
slice: get_int128s, Int128, i128, DataType::Int128
}
impl_get_multi_values! {
slice: get_uint8s, UInt8, u8, DataType::UInt8
}
impl_get_multi_values! {
slice: get_uint16s, UInt16, u16, DataType::UInt16
}
impl_get_multi_values! {
slice: get_uint32s, UInt32, u32, DataType::UInt32
}
impl_get_multi_values! {
slice: get_uint64s, UInt64, u64, DataType::UInt64
}
impl_get_multi_values! {
slice: get_uint128s, UInt128, u128, DataType::UInt128
}
impl_get_multi_values! {
slice: get_float32s, Float32, f32, DataType::Float32
}
impl_get_multi_values! {
slice: get_float64s, Float64, f64, DataType::Float64
}
impl_get_multi_values! {
vec: get_strings, String, String, DataType::String
}
impl_get_multi_values! {
slice: get_dates, Date, NaiveDate, DataType::Date
}
impl_get_multi_values! {
slice: get_times, Time, NaiveTime, DataType::Time
}
impl_get_multi_values! {
slice: get_datetimes, DateTime, NaiveDateTime, DataType::DateTime
}
impl_get_multi_values! {
slice: get_instants, Instant, DateTime<Utc>, DataType::Instant
}
impl_get_multi_values! {
vec: get_bigintegers, BigInteger, BigInt, DataType::BigInteger
}
impl_get_multi_values! {
vec: get_bigdecimals, BigDecimal, BigDecimal, DataType::BigDecimal
}
impl_set_multi_values! {
set_bools, Bool, bool, DataType::Bool
}
impl_set_multi_values! {
set_chars, Char, char, DataType::Char
}
impl_set_multi_values! {
set_int8s, Int8, i8, DataType::Int8
}
impl_set_multi_values! {
set_int16s, Int16, i16, DataType::Int16
}
impl_set_multi_values! {
set_int32s, Int32, i32, DataType::Int32
}
impl_set_multi_values! {
set_int64s, Int64, i64, DataType::Int64
}
impl_set_multi_values! {
set_int128s, Int128, i128, DataType::Int128
}
impl_set_multi_values! {
set_uint8s, UInt8, u8, DataType::UInt8
}
impl_set_multi_values! {
set_uint16s, UInt16, u16, DataType::UInt16
}
impl_set_multi_values! {
set_uint32s, UInt32, u32, DataType::UInt32
}
impl_set_multi_values! {
set_uint64s, UInt64, u64, DataType::UInt64
}
impl_set_multi_values! {
set_uint128s, UInt128, u128, DataType::UInt128
}
impl_set_multi_values! {
set_float32s, Float32, f32, DataType::Float32
}
impl_set_multi_values! {
set_float64s, Float64, f64, DataType::Float64
}
impl_set_multi_values! {
set_strings, String, String, DataType::String
}
impl_set_multi_values! {
set_dates, Date, NaiveDate, DataType::Date
}
impl_set_multi_values! {
set_times, Time, NaiveTime, DataType::Time
}
impl_set_multi_values! {
set_datetimes, DateTime, NaiveDateTime, DataType::DateTime
}
impl_set_multi_values! {
set_instants, Instant, DateTime<Utc>, DataType::Instant
}
impl_set_multi_values! {
set_bigintegers, BigInteger, BigInt, DataType::BigInteger
}
impl_set_multi_values! {
set_bigdecimals, BigDecimal, BigDecimal, DataType::BigDecimal
}
impl_set_multi_values_slice! {
set_bools_slice, Bool, bool, DataType::Bool
}
impl_set_multi_values_slice! {
set_chars_slice, Char, char, DataType::Char
}
impl_set_multi_values_slice! {
set_int8s_slice, Int8, i8, DataType::Int8
}
impl_set_multi_values_slice! {
set_int16s_slice, Int16, i16, DataType::Int16
}
impl_set_multi_values_slice! {
set_int32s_slice, Int32, i32, DataType::Int32
}
impl_set_multi_values_slice! {
set_int64s_slice, Int64, i64, DataType::Int64
}
impl_set_multi_values_slice! {
set_int128s_slice, Int128, i128, DataType::Int128
}
impl_set_multi_values_slice! {
set_uint8s_slice, UInt8, u8, DataType::UInt8
}
impl_set_multi_values_slice! {
set_uint16s_slice, UInt16, u16, DataType::UInt16
}
impl_set_multi_values_slice! {
set_uint32s_slice, UInt32, u32, DataType::UInt32
}
impl_set_multi_values_slice! {
set_uint64s_slice, UInt64, u64, DataType::UInt64
}
impl_set_multi_values_slice! {
set_uint128s_slice, UInt128, u128, DataType::UInt128
}
impl_set_multi_values_slice! {
set_float32s_slice, Float32, f32, DataType::Float32
}
impl_set_multi_values_slice! {
set_float64s_slice, Float64, f64, DataType::Float64
}
impl_set_multi_values_slice! {
set_strings_slice, String, String, DataType::String
}
impl_set_multi_values_slice! {
set_dates_slice, Date, NaiveDate, DataType::Date
}
impl_set_multi_values_slice! {
set_times_slice, Time, NaiveTime, DataType::Time
}
impl_set_multi_values_slice! {
set_datetimes_slice, DateTime, NaiveDateTime, DataType::DateTime
}
impl_set_multi_values_slice! {
set_instants_slice, Instant, DateTime<Utc>, DataType::Instant
}
impl_set_multi_values_slice! {
set_bigintegers_slice, BigInteger, BigInt, DataType::BigInteger
}
impl_set_multi_values_slice! {
set_bigdecimals_slice, BigDecimal, BigDecimal, DataType::BigDecimal
}
impl_set_single_value! {
set_bool, Bool, bool, DataType::Bool
}
impl_set_single_value! {
set_char, Char, char, DataType::Char
}
impl_set_single_value! {
set_int8, Int8, i8, DataType::Int8
}
impl_set_single_value! {
set_int16, Int16, i16, DataType::Int16
}
impl_set_single_value! {
set_int32, Int32, i32, DataType::Int32
}
impl_set_single_value! {
set_int64, Int64, i64, DataType::Int64
}
impl_set_single_value! {
set_int128, Int128, i128, DataType::Int128
}
impl_set_single_value! {
set_uint8, UInt8, u8, DataType::UInt8
}
impl_set_single_value! {
set_uint16, UInt16, u16, DataType::UInt16
}
impl_set_single_value! {
set_uint32, UInt32, u32, DataType::UInt32
}
impl_set_single_value! {
set_uint64, UInt64, u64, DataType::UInt64
}
impl_set_single_value! {
set_uint128, UInt128, u128, DataType::UInt128
}
impl_set_single_value! {
set_float32, Float32, f32, DataType::Float32
}
impl_set_single_value! {
set_float64, Float64, f64, DataType::Float64
}
impl_set_single_value! {
set_string, String, String, DataType::String
}
impl_set_single_value! {
set_date, Date, NaiveDate, DataType::Date
}
impl_set_single_value! {
set_time, Time, NaiveTime, DataType::Time
}
impl_set_single_value! {
set_datetime, DateTime, NaiveDateTime, DataType::DateTime
}
impl_set_single_value! {
set_instant, Instant, DateTime<Utc>, DataType::Instant
}
impl_set_single_value! {
set_biginteger, BigInteger, BigInt, DataType::BigInteger
}
impl_set_single_value! {
set_bigdecimal, BigDecimal, BigDecimal, DataType::BigDecimal
}
impl_add_single_value! {
add_bool, Bool, bool, DataType::Bool
}
impl_add_single_value! {
add_char, Char, char, DataType::Char
}
impl_add_single_value! {
add_int8, Int8, i8, DataType::Int8
}
impl_add_single_value! {
add_int16, Int16, i16, DataType::Int16
}
impl_add_single_value! {
add_int32, Int32, i32, DataType::Int32
}
impl_add_single_value! {
add_int64, Int64, i64, DataType::Int64
}
impl_add_single_value! {
add_int128, Int128, i128, DataType::Int128
}
impl_add_single_value! {
add_uint8, UInt8, u8, DataType::UInt8
}
impl_add_single_value! {
add_uint16, UInt16, u16, DataType::UInt16
}
impl_add_single_value! {
add_uint32, UInt32, u32, DataType::UInt32
}
impl_add_single_value! {
add_uint64, UInt64, u64, DataType::UInt64
}
impl_add_single_value! {
add_uint128, UInt128, u128, DataType::UInt128
}
impl_add_single_value! {
add_float32, Float32, f32, DataType::Float32
}
impl_add_single_value! {
add_float64, Float64, f64, DataType::Float64
}
impl_add_single_value! {
add_string, String, String, DataType::String
}
impl_add_single_value! {
add_date, Date, NaiveDate, DataType::Date
}
impl_add_single_value! {
add_time, Time, NaiveTime, DataType::Time
}
impl_add_single_value! {
add_datetime, DateTime, NaiveDateTime, DataType::DateTime
}
impl_add_single_value! {
add_instant, Instant, DateTime<Utc>, DataType::Instant
}
impl_add_single_value! {
add_biginteger, BigInteger, BigInt, DataType::BigInteger
}
impl_add_single_value! {
add_bigdecimal, BigDecimal, BigDecimal, DataType::BigDecimal
}
impl_add_multi_values! {
add_bools, Bool, bool, DataType::Bool
}
impl_add_multi_values! {
add_chars, Char, char, DataType::Char
}
impl_add_multi_values! {
add_int8s, Int8, i8, DataType::Int8
}
impl_add_multi_values! {
add_int16s, Int16, i16, DataType::Int16
}
impl_add_multi_values! {
add_int32s, Int32, i32, DataType::Int32
}
impl_add_multi_values! {
add_int64s, Int64, i64, DataType::Int64
}
impl_add_multi_values! {
add_int128s, Int128, i128, DataType::Int128
}
impl_add_multi_values! {
add_uint8s, UInt8, u8, DataType::UInt8
}
impl_add_multi_values! {
add_uint16s, UInt16, u16, DataType::UInt16
}
impl_add_multi_values! {
add_uint32s, UInt32, u32, DataType::UInt32
}
impl_add_multi_values! {
add_uint64s, UInt64, u64, DataType::UInt64
}
impl_add_multi_values! {
add_uint128s, UInt128, u128, DataType::UInt128
}
impl_add_multi_values! {
add_float32s, Float32, f32, DataType::Float32
}
impl_add_multi_values! {
add_float64s, Float64, f64, DataType::Float64
}
impl_add_multi_values! {
add_strings, String, String, DataType::String
}
impl_add_multi_values! {
add_dates, Date, NaiveDate, DataType::Date
}
impl_add_multi_values! {
add_times, Time, NaiveTime, DataType::Time
}
impl_add_multi_values! {
add_datetimes, DateTime, NaiveDateTime, DataType::DateTime
}
impl_add_multi_values! {
add_instants, Instant, DateTime<Utc>, DataType::Instant
}
impl_add_multi_values! {
add_bigintegers, BigInteger, BigInt, DataType::BigInteger
}
impl_add_multi_values! {
add_bigdecimals, BigDecimal, BigDecimal, DataType::BigDecimal
}
impl_add_multi_values_slice! {
add_bools_slice, Bool, bool, DataType::Bool
}
impl_add_multi_values_slice! {
add_chars_slice, Char, char, DataType::Char
}
impl_add_multi_values_slice! {
add_int8s_slice, Int8, i8, DataType::Int8
}
impl_add_multi_values_slice! {
add_int16s_slice, Int16, i16, DataType::Int16
}
impl_add_multi_values_slice! {
add_int32s_slice, Int32, i32, DataType::Int32
}
impl_add_multi_values_slice! {
add_int64s_slice, Int64, i64, DataType::Int64
}
impl_add_multi_values_slice! {
add_int128s_slice, Int128, i128, DataType::Int128
}
impl_add_multi_values_slice! {
add_uint8s_slice, UInt8, u8, DataType::UInt8
}
impl_add_multi_values_slice! {
add_uint16s_slice, UInt16, u16, DataType::UInt16
}
impl_add_multi_values_slice! {
add_uint32s_slice, UInt32, u32, DataType::UInt32
}
impl_add_multi_values_slice! {
add_uint64s_slice, UInt64, u64, DataType::UInt64
}
impl_add_multi_values_slice! {
add_uint128s_slice, UInt128, u128, DataType::UInt128
}
impl_add_multi_values_slice! {
add_float32s_slice, Float32, f32, DataType::Float32
}
impl_add_multi_values_slice! {
add_float64s_slice, Float64, f64, DataType::Float64
}
impl_add_multi_values_slice! {
add_strings_slice, String, String, DataType::String
}
impl_add_multi_values_slice! {
add_dates_slice, Date, NaiveDate, DataType::Date
}
impl_add_multi_values_slice! {
add_times_slice, Time, NaiveTime, DataType::Time
}
impl_add_multi_values_slice! {
add_datetimes_slice, DateTime, NaiveDateTime, DataType::DateTime
}
impl_add_multi_values_slice! {
add_instants_slice, Instant, DateTime<Utc>, DataType::Instant
}
impl_add_multi_values_slice! {
add_bigintegers_slice, BigInteger, BigInt, DataType::BigInteger
}
impl_add_multi_values_slice! {
add_bigdecimals_slice, BigDecimal, BigDecimal, DataType::BigDecimal
}
pub fn merge(&mut self, other: &MultiValues) -> ValueResult<()> {
if self.data_type() != other.data_type() {
return Err(ValueError::TypeMismatch {
expected: self.data_type(),
actual: other.data_type(),
});
}
match (self, other) {
(MultiValues::Bool(v), MultiValues::Bool(o)) => v.extend_from_slice(o),
(MultiValues::Char(v), MultiValues::Char(o)) => v.extend_from_slice(o),
(MultiValues::Int8(v), MultiValues::Int8(o)) => v.extend_from_slice(o),
(MultiValues::Int16(v), MultiValues::Int16(o)) => v.extend_from_slice(o),
(MultiValues::Int32(v), MultiValues::Int32(o)) => v.extend_from_slice(o),
(MultiValues::Int64(v), MultiValues::Int64(o)) => v.extend_from_slice(o),
(MultiValues::Int128(v), MultiValues::Int128(o)) => v.extend_from_slice(o),
(MultiValues::UInt8(v), MultiValues::UInt8(o)) => v.extend_from_slice(o),
(MultiValues::UInt16(v), MultiValues::UInt16(o)) => v.extend_from_slice(o),
(MultiValues::UInt32(v), MultiValues::UInt32(o)) => v.extend_from_slice(o),
(MultiValues::UInt64(v), MultiValues::UInt64(o)) => v.extend_from_slice(o),
(MultiValues::UInt128(v), MultiValues::UInt128(o)) => v.extend_from_slice(o),
(MultiValues::Float32(v), MultiValues::Float32(o)) => v.extend_from_slice(o),
(MultiValues::Float64(v), MultiValues::Float64(o)) => v.extend_from_slice(o),
(MultiValues::String(v), MultiValues::String(o)) => v.extend_from_slice(o),
(MultiValues::Date(v), MultiValues::Date(o)) => v.extend_from_slice(o),
(MultiValues::Time(v), MultiValues::Time(o)) => v.extend_from_slice(o),
(MultiValues::DateTime(v), MultiValues::DateTime(o)) => v.extend_from_slice(o),
(MultiValues::Instant(v), MultiValues::Instant(o)) => v.extend_from_slice(o),
(MultiValues::BigInteger(v), MultiValues::BigInteger(o)) => v.extend_from_slice(o),
(MultiValues::BigDecimal(v), MultiValues::BigDecimal(o)) => v.extend_from_slice(o),
(MultiValues::Empty(_), _) => {}
_ => unreachable!(),
}
Ok(())
}
}
impl Default for MultiValues {
fn default() -> Self {
MultiValues::Empty(DataType::String)
}
}
impl From<Value> for MultiValues {
fn from(value: Value) -> Self {
match value {
Value::Empty(dt) => MultiValues::Empty(dt),
Value::Bool(v) => MultiValues::Bool(vec![v]),
Value::Char(v) => MultiValues::Char(vec![v]),
Value::Int8(v) => MultiValues::Int8(vec![v]),
Value::Int16(v) => MultiValues::Int16(vec![v]),
Value::Int32(v) => MultiValues::Int32(vec![v]),
Value::Int64(v) => MultiValues::Int64(vec![v]),
Value::Int128(v) => MultiValues::Int128(vec![v]),
Value::UInt8(v) => MultiValues::UInt8(vec![v]),
Value::UInt16(v) => MultiValues::UInt16(vec![v]),
Value::UInt32(v) => MultiValues::UInt32(vec![v]),
Value::UInt64(v) => MultiValues::UInt64(vec![v]),
Value::UInt128(v) => MultiValues::UInt128(vec![v]),
Value::Float32(v) => MultiValues::Float32(vec![v]),
Value::Float64(v) => MultiValues::Float64(vec![v]),
Value::String(v) => MultiValues::String(vec![v]),
Value::Date(v) => MultiValues::Date(vec![v]),
Value::Time(v) => MultiValues::Time(vec![v]),
Value::DateTime(v) => MultiValues::DateTime(vec![v]),
Value::Instant(v) => MultiValues::Instant(vec![v]),
Value::BigInteger(v) => MultiValues::BigInteger(vec![v]),
Value::BigDecimal(v) => MultiValues::BigDecimal(vec![v]),
}
}
}
#[doc(hidden)]
pub trait MultiValuesGetter<T> {
fn get_values(&self) -> ValueResult<Vec<T>>;
}
#[doc(hidden)]
pub trait MultiValuesFirstGetter<T> {
fn get_first_value(&self) -> ValueResult<T>;
}
#[doc(hidden)]
pub trait MultiValuesSetter<T> {
fn set_values(&mut self, values: Vec<T>) -> ValueResult<()>;
}
#[doc(hidden)]
pub trait MultiValuesSetArg<'a> {
type Item: 'a + Clone;
fn apply(self, target: &mut MultiValues) -> ValueResult<()>;
}
#[doc(hidden)]
pub trait MultiValuesSetterSlice<T> {
fn set_values_slice(&mut self, values: &[T]) -> ValueResult<()>;
}
#[doc(hidden)]
pub trait MultiValuesSingleSetter<T> {
fn set_single_value(&mut self, value: T) -> ValueResult<()>;
}
#[doc(hidden)]
pub trait MultiValuesAdder<T> {
fn add_value(&mut self, value: T) -> ValueResult<()>;
}
#[doc(hidden)]
pub trait MultiValuesMultiAdder<T> {
fn add_values(&mut self, values: Vec<T>) -> ValueResult<()>;
}
#[doc(hidden)]
pub trait MultiValuesAddArg<'a> {
type Item: 'a + Clone;
fn apply_add(self, target: &mut MultiValues) -> ValueResult<()>;
}
#[doc(hidden)]
pub(crate) trait MultiValuesMultiAdderSlice<T> {
fn add_values_slice(&mut self, values: &[T]) -> ValueResult<()>;
}
#[doc(hidden)]
pub(crate) trait MultiValuesConstructor<T> {
fn from_vec(values: Vec<T>) -> Self;
}
macro_rules! impl_multi_value_traits {
($type:ty, $variant:ident, $data_type:expr) => {
impl MultiValuesGetter<$type> for MultiValues {
fn get_values(&self) -> ValueResult<Vec<$type>> {
match self {
MultiValues::$variant(v) => Ok(v.clone()),
MultiValues::Empty(_) => Ok(Vec::new()),
_ => Err(ValueError::TypeMismatch {
expected: $data_type,
actual: self.data_type(),
}),
}
}
}
impl MultiValuesFirstGetter<$type> for MultiValues {
fn get_first_value(&self) -> ValueResult<$type> {
match self {
MultiValues::$variant(v) if !v.is_empty() => Ok(v[0].clone()),
MultiValues::$variant(_) | MultiValues::Empty(_) => Err(ValueError::NoValue),
_ => Err(ValueError::TypeMismatch {
expected: $data_type,
actual: self.data_type(),
}),
}
}
}
impl MultiValuesSetter<$type> for MultiValues {
fn set_values(&mut self, values: Vec<$type>) -> ValueResult<()> {
*self = MultiValues::$variant(values);
Ok(())
}
}
impl MultiValuesSetterSlice<$type> for MultiValues {
fn set_values_slice(&mut self, values: &[$type]) -> ValueResult<()> {
*self = MultiValues::$variant(values.to_vec());
Ok(())
}
}
impl MultiValuesSingleSetter<$type> for MultiValues {
fn set_single_value(&mut self, value: $type) -> ValueResult<()> {
*self = MultiValues::$variant(vec![value]);
Ok(())
}
}
impl MultiValuesAdder<$type> for MultiValues {
fn add_value(&mut self, value: $type) -> ValueResult<()> {
match self {
MultiValues::$variant(v) => {
v.push(value);
Ok(())
}
MultiValues::Empty(dt) if *dt == $data_type => {
*self = MultiValues::$variant(vec![value]);
Ok(())
}
_ => Err(ValueError::TypeMismatch {
expected: $data_type,
actual: self.data_type(),
}),
}
}
}
impl<'a> MultiValuesSetArg<'a> for Vec<$type> {
type Item = $type;
fn apply(self, target: &mut MultiValues) -> ValueResult<()> {
<MultiValues as MultiValuesSetter<$type>>::set_values(target, self)
}
}
impl<'a> MultiValuesSetArg<'a> for &'a [$type]
where
$type: Clone,
{
type Item = $type;
fn apply(self, target: &mut MultiValues) -> ValueResult<()> {
<MultiValues as MultiValuesSetterSlice<$type>>::set_values_slice(target, self)
}
}
impl<'a> MultiValuesSetArg<'a> for $type {
type Item = $type;
fn apply(self, target: &mut MultiValues) -> ValueResult<()> {
<MultiValues as MultiValuesSingleSetter<$type>>::set_single_value(target, self)
}
}
impl MultiValuesMultiAdder<$type> for MultiValues {
fn add_values(&mut self, values: Vec<$type>) -> ValueResult<()> {
match self {
MultiValues::$variant(v) => {
v.extend(values);
Ok(())
}
MultiValues::Empty(dt) if *dt == $data_type => {
*self = MultiValues::$variant(values);
Ok(())
}
_ => Err(ValueError::TypeMismatch {
expected: $data_type,
actual: self.data_type(),
}),
}
}
}
impl MultiValuesMultiAdderSlice<$type> for MultiValues {
fn add_values_slice(&mut self, values: &[$type]) -> ValueResult<()> {
match self {
MultiValues::$variant(v) => {
v.extend_from_slice(values);
Ok(())
}
MultiValues::Empty(dt) if *dt == $data_type => {
*self = MultiValues::$variant(values.to_vec());
Ok(())
}
_ => Err(ValueError::TypeMismatch {
expected: $data_type,
actual: self.data_type(),
}),
}
}
}
impl<'a> MultiValuesAddArg<'a> for $type {
type Item = $type;
fn apply_add(self, target: &mut MultiValues) -> ValueResult<()> {
<MultiValues as MultiValuesAdder<$type>>::add_value(target, self)
}
}
impl<'a> MultiValuesAddArg<'a> for Vec<$type> {
type Item = $type;
fn apply_add(self, target: &mut MultiValues) -> ValueResult<()> {
<MultiValues as MultiValuesMultiAdder<$type>>::add_values(target, self)
}
}
impl<'a> MultiValuesAddArg<'a> for &'a [$type]
where
$type: Clone,
{
type Item = $type;
fn apply_add(self, target: &mut MultiValues) -> ValueResult<()> {
<MultiValues as MultiValuesMultiAdderSlice<$type>>::add_values_slice(target, self)
}
}
impl MultiValuesConstructor<$type> for MultiValues {
fn from_vec(values: Vec<$type>) -> Self {
MultiValues::$variant(values)
}
}
};
}
impl_multi_value_traits!(bool, Bool, DataType::Bool);
impl_multi_value_traits!(char, Char, DataType::Char);
impl_multi_value_traits!(i8, Int8, DataType::Int8);
impl_multi_value_traits!(i16, Int16, DataType::Int16);
impl_multi_value_traits!(i32, Int32, DataType::Int32);
impl_multi_value_traits!(i64, Int64, DataType::Int64);
impl_multi_value_traits!(i128, Int128, DataType::Int128);
impl_multi_value_traits!(u8, UInt8, DataType::UInt8);
impl_multi_value_traits!(u16, UInt16, DataType::UInt16);
impl_multi_value_traits!(u32, UInt32, DataType::UInt32);
impl_multi_value_traits!(u64, UInt64, DataType::UInt64);
impl_multi_value_traits!(u128, UInt128, DataType::UInt128);
impl_multi_value_traits!(f32, Float32, DataType::Float32);
impl_multi_value_traits!(f64, Float64, DataType::Float64);
impl_multi_value_traits!(String, String, DataType::String);
impl_multi_value_traits!(NaiveDate, Date, DataType::Date);
impl_multi_value_traits!(NaiveTime, Time, DataType::Time);
impl_multi_value_traits!(NaiveDateTime, DateTime, DataType::DateTime);
impl_multi_value_traits!(DateTime<Utc>, Instant, DataType::Instant);
impl_multi_value_traits!(BigInt, BigInteger, DataType::BigInteger);
impl_multi_value_traits!(BigDecimal, BigDecimal, DataType::BigDecimal);
impl MultiValuesSetArg<'_> for &str {
type Item = String;
fn apply(self, target: &mut MultiValues) -> ValueResult<()> {
<MultiValues as MultiValuesSingleSetter<String>>::set_single_value(target, self.to_string())
}
}
impl MultiValuesSetArg<'_> for Vec<&str> {
type Item = String;
fn apply(self, target: &mut MultiValues) -> ValueResult<()> {
let owned: Vec<String> = self.into_iter().map(|s| s.to_string()).collect();
<MultiValues as MultiValuesSetter<String>>::set_values(target, owned)
}
}
impl<'b> MultiValuesSetArg<'_> for &'b [&'b str] {
type Item = String;
fn apply(self, target: &mut MultiValues) -> ValueResult<()> {
let owned: Vec<String> = self.iter().map(|s| (*s).to_string()).collect();
<MultiValues as MultiValuesSetter<String>>::set_values(target, owned)
}
}
impl MultiValuesAddArg<'_> for &str {
type Item = String;
fn apply_add(self, target: &mut MultiValues) -> ValueResult<()> {
<MultiValues as MultiValuesAdder<String>>::add_value(target, self.to_string())
}
}
impl MultiValuesAddArg<'_> for Vec<&str> {
type Item = String;
fn apply_add(self, target: &mut MultiValues) -> ValueResult<()> {
let owned: Vec<String> = self.into_iter().map(|s| s.to_string()).collect();
<MultiValues as MultiValuesMultiAdder<String>>::add_values(target, owned)
}
}
impl<'b> MultiValuesAddArg<'_> for &'b [&'b str] {
type Item = String;
fn apply_add(self, target: &mut MultiValues) -> ValueResult<()> {
let owned: Vec<String> = self.iter().map(|s| (*s).to_string()).collect();
<MultiValues as MultiValuesMultiAdder<String>>::add_values(target, owned)
}
}