use std::{borrow::Cow, fmt::Display, str::Utf8Error};
use rust_decimal::prelude::*;
use serde::{Deserialize, Serialize};
use super::{Timestamp, Ty};
#[derive(Debug, Clone)]
pub enum BorrowedValue<'b> {
Null(Ty), Bool(bool), TinyInt(i8), SmallInt(i16),
Int(i32),
BigInt(i64),
Float(f32),
Double(f64),
VarChar(&'b str),
Timestamp(Timestamp),
NChar(Cow<'b, str>),
UTinyInt(u8),
USmallInt(u16),
UInt(u32),
UBigInt(u64), Json(Cow<'b, [u8]>),
VarBinary(&'b [u8]),
Decimal(Decimal),
Blob(&'b [u8]),
MediumBlob(&'b [u8]),
}
macro_rules! borrowed_value_to_native {
($v:expr) => {
match $v {
BorrowedValue::Null(_) => None,
BorrowedValue::Bool(v) => Some(if *v { 1 } else { 0 }),
BorrowedValue::TinyInt(v) => Some(*v as _),
BorrowedValue::SmallInt(v) => Some(*v as _),
BorrowedValue::Int(v) => Some(*v as _),
BorrowedValue::BigInt(v) => Some(*v as _),
BorrowedValue::Float(v) => Some(*v as _),
BorrowedValue::Double(v) => Some(*v as _),
BorrowedValue::VarChar(s) => s.parse().map(Some).unwrap_or(None),
BorrowedValue::Timestamp(v) => Some(v.as_raw_i64() as _),
BorrowedValue::NChar(s) => s.parse().map(Some).unwrap_or(None),
BorrowedValue::UTinyInt(v) => Some(*v as _),
BorrowedValue::USmallInt(v) => Some(*v as _),
BorrowedValue::UInt(v) => Some(*v as _),
BorrowedValue::UBigInt(v) => Some(*v as _),
BorrowedValue::Json(v) => serde_json::from_slice(&v).ok(),
BorrowedValue::VarBinary(_) => todo!(),
BorrowedValue::Decimal(_) => todo!(),
BorrowedValue::Blob(_) => todo!(),
BorrowedValue::MediumBlob(_) => todo!(),
}
};
}
macro_rules! borrowed_value_to_float {
($v:expr) => {
match $v {
BorrowedValue::Null(_) => None,
BorrowedValue::Bool(v) => Some(if *v { 1. } else { 0. }),
BorrowedValue::TinyInt(v) => Some(*v as _),
BorrowedValue::SmallInt(v) => Some(*v as _),
BorrowedValue::Int(v) => Some(*v as _),
BorrowedValue::BigInt(v) => Some(*v as _),
BorrowedValue::Float(v) => Some(*v as _),
BorrowedValue::Double(v) => Some(*v as _),
BorrowedValue::VarChar(s) => s.parse().map(Some).unwrap_or(None),
BorrowedValue::Timestamp(v) => Some(v.as_raw_i64() as _),
BorrowedValue::NChar(s) => s.parse().map(Some).unwrap_or(None),
BorrowedValue::UTinyInt(v) => Some(*v as _),
BorrowedValue::USmallInt(v) => Some(*v as _),
BorrowedValue::UInt(v) => Some(*v as _),
BorrowedValue::UBigInt(v) => Some(*v as _),
BorrowedValue::Json(v) => serde_json::from_slice(&v).ok(),
BorrowedValue::VarBinary(_) => todo!(),
BorrowedValue::Decimal(_) => todo!(),
BorrowedValue::Blob(_) => todo!(),
BorrowedValue::MediumBlob(_) => todo!(),
}
};
}
impl<'b> BorrowedValue<'b> {
pub const fn ty(&self) -> Ty {
use BorrowedValue::*;
match self {
Null(ty) => *ty,
Bool(_) => Ty::Bool,
TinyInt(_) => Ty::TinyInt,
SmallInt(_) => Ty::SmallInt,
Int(_) => Ty::Int,
BigInt(_) => Ty::BigInt,
UTinyInt(_) => Ty::UTinyInt,
USmallInt(_) => Ty::USmallInt,
UInt(_) => Ty::UInt,
UBigInt(_) => Ty::UBigInt,
Float(_) => Ty::Float,
Double(_) => Ty::Double,
VarChar(_) => Ty::VarChar,
Timestamp(_) => Ty::Timestamp,
Json(_) => Ty::Json,
NChar(_) => Ty::NChar,
VarBinary(_) => Ty::VarBinary,
Decimal(_) => Ty::Decimal,
Blob(_) => Ty::Blob,
MediumBlob(_) => Ty::MediumBlob,
}
}
pub fn to_sql_value(&self) -> String {
use BorrowedValue::*;
match self {
Null(_) => "NULL".to_string(),
Bool(v) => format!("{v}"),
TinyInt(v) => format!("{v}"),
SmallInt(v) => format!("{v}"),
Int(v) => format!("{v}"),
BigInt(v) => format!("{v}"),
Float(v) => format!("{v}"),
Double(v) => format!("{v}"),
VarChar(v) => format!("\"{}\"", v.escape_debug()),
Timestamp(v) => format!("{}", v.as_raw_i64()),
NChar(v) => format!("\"{}\"", v.escape_debug()),
UTinyInt(v) => format!("{v}"),
USmallInt(v) => format!("{v}"),
UInt(v) => format!("{v}"),
UBigInt(v) => format!("{v}"),
Json(v) => format!("\"{}\"", unsafe { std::str::from_utf8_unchecked(v) }),
VarBinary(_) => todo!(),
Decimal(_) => todo!(),
Blob(_) => todo!(),
MediumBlob(_) => todo!(),
}
}
pub const fn is_null(&self) -> bool {
matches!(self, BorrowedValue::Null(_))
}
fn strict_as_str(&self) -> &str {
use BorrowedValue::*;
match self {
VarChar(v) => v,
NChar(v) => v,
Null(_) => panic!("expect str but value is null"),
Timestamp(_) => panic!("expect str but value is timestamp"),
_ => panic!("expect str but only varchar/binary/nchar is supported"),
}
}
pub fn to_string(&self) -> Result<String, Utf8Error> {
use BorrowedValue::*;
match self {
Null(_) => Ok(String::new()),
Bool(v) => Ok(format!("{v}")),
VarChar(v) => Ok(v.to_string()),
Json(v) => Ok(unsafe { std::str::from_utf8_unchecked(v) }.to_string()),
NChar(v) => Ok(v.to_string()),
TinyInt(v) => Ok(format!("{v}")),
SmallInt(v) => Ok(format!("{v}")),
Int(v) => Ok(format!("{v}")),
BigInt(v) => Ok(format!("{v}")),
UTinyInt(v) => Ok(format!("{v}")),
USmallInt(v) => Ok(format!("{v}")),
UInt(v) => Ok(format!("{v}")),
UBigInt(v) => Ok(format!("{v}")),
Float(v) => Ok(format!("{v}")),
Double(v) => Ok(format!("{v}")),
Timestamp(v) => Ok(v.to_datetime_with_tz().to_rfc3339()),
_ => unreachable!("un supported type to string"),
}
}
pub fn to_value(&self) -> Value {
use BorrowedValue::*;
match self {
Null(ty) => Value::Null(*ty),
Bool(v) => Value::Bool(*v),
TinyInt(v) => Value::TinyInt(*v),
SmallInt(v) => Value::SmallInt(*v),
Int(v) => Value::Int(*v),
BigInt(v) => Value::BigInt(*v),
UTinyInt(v) => Value::UTinyInt(*v),
USmallInt(v) => Value::USmallInt(*v),
UInt(v) => Value::UInt(*v),
UBigInt(v) => Value::UBigInt(*v),
Float(v) => Value::Float(*v),
Double(v) => Value::Double(*v),
VarChar(v) => Value::VarChar(v.to_string()),
Timestamp(v) => Value::Timestamp(*v),
Json(v) => {
Value::Json(serde_json::from_slice(v).expect("json should always be deserialized"))
}
NChar(str) => Value::NChar(str.to_string()),
VarBinary(_) => todo!(),
Decimal(_) => todo!(),
Blob(_) => todo!(),
MediumBlob(_) => todo!(),
}
}
pub fn to_json_value(&self) -> serde_json::Value {
use BorrowedValue::*;
match self {
Null(_) => serde_json::Value::Null,
Bool(v) => serde_json::Value::Bool(*v),
TinyInt(v) => serde_json::Value::Number(serde_json::Number::from(*v)),
SmallInt(v) => serde_json::Value::Number(serde_json::Number::from(*v)),
Int(v) => serde_json::Value::Number(serde_json::Number::from(*v)),
BigInt(v) => serde_json::Value::Number(serde_json::Number::from(*v)),
UTinyInt(v) => serde_json::Value::Number(serde_json::Number::from(*v)),
USmallInt(v) => serde_json::Value::Number(serde_json::Number::from(*v)),
UInt(v) => serde_json::Value::Number(serde_json::Number::from(*v)),
UBigInt(v) => serde_json::Value::Number(serde_json::Number::from(*v)),
Float(v) => serde_json::Value::Number(serde_json::Number::from_f64(*v as f64).unwrap()),
Double(v) => serde_json::Value::Number(serde_json::Number::from_f64(*v).unwrap()),
VarChar(v) => serde_json::Value::String(v.to_string()),
Timestamp(v) => serde_json::Value::Number(serde_json::Number::from(v.as_raw_i64())),
Json(v) => serde_json::Value::Number(
serde_json::from_slice(v).expect("json should always be deserialized"),
),
NChar(str) => serde_json::Value::String(str.to_string()),
VarBinary(_) => todo!(),
Decimal(_) => todo!(),
Blob(_) => todo!(),
MediumBlob(_) => todo!(),
}
}
#[inline]
pub fn into_value(self) -> Value {
use BorrowedValue::*;
match self {
Null(ty) => Value::Null(ty),
Bool(v) => Value::Bool(v),
TinyInt(v) => Value::TinyInt(v),
SmallInt(v) => Value::SmallInt(v),
Int(v) => Value::Int(v),
BigInt(v) => Value::BigInt(v),
UTinyInt(v) => Value::UTinyInt(v),
USmallInt(v) => Value::USmallInt(v),
UInt(v) => Value::UInt(v),
UBigInt(v) => Value::UBigInt(v),
Float(v) => Value::Float(v),
Double(v) => Value::Double(v),
VarChar(v) => Value::VarChar(v.to_string()),
Timestamp(v) => Value::Timestamp(v),
Json(v) => {
Value::Json(serde_json::from_slice(&v).expect("json should always be deserialized"))
}
NChar(str) => Value::NChar(str.to_string()),
VarBinary(_) => todo!(),
Decimal(_) => todo!(),
Blob(_) => todo!(),
MediumBlob(_) => todo!(),
}
}
pub(crate) fn to_bool(&self) -> Option<bool> {
match self {
BorrowedValue::Null(_) => None,
BorrowedValue::Bool(v) => Some(*v),
BorrowedValue::TinyInt(v) => Some(*v > 0),
BorrowedValue::SmallInt(v) => Some(*v > 0),
BorrowedValue::Int(v) => Some(*v > 0),
BorrowedValue::BigInt(v) => Some(*v > 0),
BorrowedValue::Float(v) => Some(*v > 0.),
BorrowedValue::Double(v) => Some(*v > 0.),
BorrowedValue::VarChar(s) => match *s {
"" => None,
"false" | "f" | "F" | "FALSE" | "False" => Some(false),
"true" | "t" | "T" | "TRUE" | "True" => Some(true),
_ => Some(true),
},
BorrowedValue::Timestamp(_) => Some(true),
BorrowedValue::NChar(s) => match s.as_ref() {
"" => None,
"false" | "f" | "F" | "FALSE" | "False" => Some(false),
"true" | "t" | "T" | "TRUE" | "True" => Some(true),
_ => Some(true),
},
BorrowedValue::UTinyInt(v) => Some(*v != 0),
BorrowedValue::USmallInt(v) => Some(*v != 0),
BorrowedValue::UInt(v) => Some(*v != 0),
BorrowedValue::UBigInt(v) => Some(*v != 0),
BorrowedValue::Json(_) => Some(true),
BorrowedValue::VarBinary(_) => todo!(),
BorrowedValue::Decimal(_) => todo!(),
BorrowedValue::Blob(_) => todo!(),
BorrowedValue::MediumBlob(_) => todo!(),
}
}
pub(crate) fn to_i8(&self) -> Option<i8> {
borrowed_value_to_native!(self)
}
pub(crate) fn to_i16(&self) -> Option<i16> {
borrowed_value_to_native!(self)
}
pub(crate) fn to_i32(&self) -> Option<i32> {
borrowed_value_to_native!(self)
}
pub(crate) fn to_i64(&self) -> Option<i64> {
borrowed_value_to_native!(self)
}
pub(crate) fn to_u8(&self) -> Option<u8> {
borrowed_value_to_native!(self)
}
pub(crate) fn to_u16(&self) -> Option<u16> {
borrowed_value_to_native!(self)
}
pub(crate) fn to_u32(&self) -> Option<u32> {
borrowed_value_to_native!(self)
}
pub(crate) fn to_u64(&self) -> Option<u64> {
borrowed_value_to_native!(self)
}
pub(crate) fn to_f32(&self) -> Option<f32> {
borrowed_value_to_float!(self)
}
pub(crate) fn to_f64(&self) -> Option<f64> {
borrowed_value_to_float!(self)
}
pub(crate) fn to_str(&self) -> Option<Cow<str>> {
match self {
BorrowedValue::Null(_) => None,
BorrowedValue::Bool(v) => Some(v.to_string().into()),
BorrowedValue::TinyInt(v) => Some(v.to_string().into()),
BorrowedValue::SmallInt(v) => Some(v.to_string().into()),
BorrowedValue::Int(v) => Some(v.to_string().into()),
BorrowedValue::BigInt(v) => Some(v.to_string().into()),
BorrowedValue::Float(v) => Some(v.to_string().into()),
BorrowedValue::Double(v) => Some(v.to_string().into()),
BorrowedValue::VarChar(s) => Some((*s).into()),
BorrowedValue::Timestamp(v) => Some(v.to_datetime_with_tz().to_string().into()),
BorrowedValue::NChar(s) => Some(s.as_ref().into()),
BorrowedValue::UTinyInt(v) => Some(v.to_string().into()),
BorrowedValue::USmallInt(v) => Some(v.to_string().into()),
BorrowedValue::UInt(v) => Some(v.to_string().into()),
BorrowedValue::UBigInt(v) => Some(v.to_string().into()),
BorrowedValue::Json(v) => Some(unsafe { std::str::from_utf8_unchecked(v) }.into()),
BorrowedValue::VarBinary(_) => todo!(),
BorrowedValue::Decimal(_) => todo!(),
BorrowedValue::Blob(_) => todo!(),
BorrowedValue::MediumBlob(_) => todo!(),
}
}
pub(crate) fn to_timestamp(&self) -> Option<Timestamp> {
match self {
BorrowedValue::Null(_) => None,
BorrowedValue::Timestamp(v) => Some(*v),
_ => panic!("Unsupported conversion from {} to timestamp", self.ty()),
}
}
}
impl<'b> Display for BorrowedValue<'b> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
use BorrowedValue::*;
match self {
Null(_) => f.write_str("NULL"),
Bool(v) => f.write_fmt(format_args!("{v}")),
TinyInt(v) => f.write_fmt(format_args!("{v}")),
SmallInt(v) => f.write_fmt(format_args!("{v}")),
Int(v) => f.write_fmt(format_args!("{v}")),
BigInt(v) => f.write_fmt(format_args!("{v}")),
Float(v) => f.write_fmt(format_args!("{v}")),
Double(v) => f.write_fmt(format_args!("{v}")),
VarChar(v) => f.write_fmt(format_args!("{v}")),
Timestamp(v) => f.write_fmt(format_args!("{v}")),
NChar(v) => f.write_fmt(format_args!("{v}")),
UTinyInt(v) => f.write_fmt(format_args!("{v}")),
USmallInt(v) => f.write_fmt(format_args!("{v}")),
UInt(v) => f.write_fmt(format_args!("{v}")),
UBigInt(v) => f.write_fmt(format_args!("{v}")),
Json(v) => f.write_fmt(format_args!("{}", v.as_ref().escape_ascii())),
VarBinary(_) => todo!(),
Decimal(_) => todo!(),
Blob(_) => todo!(),
MediumBlob(_) => todo!(),
}
}
}
unsafe impl<'b> Send for BorrowedValue<'b> {}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
pub enum Value {
Null(Ty), Bool(bool), TinyInt(i8), SmallInt(i16),
Int(i32),
BigInt(i64),
Float(f32),
Double(f64),
VarChar(String),
Timestamp(Timestamp),
NChar(String),
UTinyInt(u8),
USmallInt(u16),
UInt(u32),
UBigInt(u64), Json(serde_json::Value),
VarBinary(Vec<u8>),
Decimal(Decimal),
Blob(Vec<u8>),
MediumBlob(Vec<u8>),
}
impl Display for Value {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
use Value::*;
match self {
Null(_) => f.write_str("NULL"),
Bool(v) => f.write_fmt(format_args!("{v}")),
TinyInt(v) => f.write_fmt(format_args!("{v}")),
SmallInt(v) => f.write_fmt(format_args!("{v}")),
Int(v) => f.write_fmt(format_args!("{v}")),
BigInt(v) => f.write_fmt(format_args!("{v}")),
Float(v) => f.write_fmt(format_args!("{v}")),
Double(v) => f.write_fmt(format_args!("{v}")),
VarChar(v) => f.write_fmt(format_args!("{v}")),
Timestamp(v) => f.write_fmt(format_args!("{v}")),
NChar(v) => f.write_fmt(format_args!("{v}")),
UTinyInt(v) => f.write_fmt(format_args!("{v}")),
USmallInt(v) => f.write_fmt(format_args!("{v}")),
UInt(v) => f.write_fmt(format_args!("{v}")),
UBigInt(v) => f.write_fmt(format_args!("{v}")),
Json(v) => f.write_fmt(format_args!("{v}")),
VarBinary(_) => todo!(),
Decimal(_) => todo!(),
Blob(_) => todo!(),
MediumBlob(_) => todo!(),
}
}
}
impl Value {
pub const fn ty(&self) -> Ty {
use Value::*;
match self {
Null(ty) => *ty,
Bool(_) => Ty::Bool,
TinyInt(_) => Ty::TinyInt,
SmallInt(_) => Ty::SmallInt,
Int(_) => Ty::Int,
BigInt(_) => Ty::BigInt,
UTinyInt(_) => Ty::UTinyInt,
USmallInt(_) => Ty::USmallInt,
UInt(_) => Ty::UInt,
UBigInt(_) => Ty::UBigInt,
Float(_) => Ty::Float,
Double(_) => Ty::Double,
VarChar(_) => Ty::VarChar,
Timestamp(_) => Ty::Timestamp,
Json(_) => Ty::Json,
NChar(_) => Ty::NChar,
VarBinary(_) => Ty::VarBinary,
Decimal(_) => Ty::Decimal,
Blob(_) => Ty::Blob,
MediumBlob(_) => Ty::MediumBlob,
}
}
pub fn to_borrowed_value(&self) -> BorrowedValue {
use Value::*;
match self {
Null(ty) => BorrowedValue::Null(*ty),
Bool(v) => BorrowedValue::Bool(*v),
TinyInt(v) => BorrowedValue::TinyInt(*v),
SmallInt(v) => BorrowedValue::SmallInt(*v),
Int(v) => BorrowedValue::Int(*v),
BigInt(v) => BorrowedValue::BigInt(*v),
UTinyInt(v) => BorrowedValue::UTinyInt(*v),
USmallInt(v) => BorrowedValue::USmallInt(*v),
UInt(v) => BorrowedValue::UInt(*v),
UBigInt(v) => BorrowedValue::UBigInt(*v),
Float(v) => BorrowedValue::Float(*v),
Double(v) => BorrowedValue::Double(*v),
VarChar(v) => BorrowedValue::VarChar(v),
Timestamp(v) => BorrowedValue::Timestamp(*v),
Json(j) => BorrowedValue::Json(j.to_string().into_bytes().into()),
NChar(v) => BorrowedValue::NChar(v.as_str().into()),
VarBinary(v) => BorrowedValue::VarBinary(v),
Decimal(v) => BorrowedValue::Decimal(*v),
Blob(v) => BorrowedValue::Blob(v),
MediumBlob(v) => BorrowedValue::MediumBlob(v),
}
}
pub const fn is_null(&self) -> bool {
matches!(self, Value::Null(_))
}
pub fn strict_as_str(&self) -> &str {
use Value::*;
match self {
VarChar(v) => v.as_str(),
NChar(v) => v.as_str(),
Json(v) => v.as_str().expect("invalid str type"),
Null(_) => "Null",
Timestamp(_) => panic!("expect str but value is timestamp"),
_ => panic!("expect str but only varchar/binary/json/nchar is supported"),
}
}
pub fn to_sql_value(&self) -> String {
use Value::*;
match self {
Null(_) => "NULL".to_string(),
Bool(v) => format!("{v}"),
TinyInt(v) => format!("{v}"),
SmallInt(v) => format!("{v}"),
Int(v) => format!("{v}"),
BigInt(v) => format!("{v}"),
Float(v) => format!("{v}"),
Double(v) => format!("{v}"),
VarChar(v) => format!("\"{}\"", v.escape_debug()),
Timestamp(v) => format!("{}", v.as_raw_i64()),
NChar(v) => format!("\"{}\"", v.escape_debug()),
UTinyInt(v) => format!("{v}"),
USmallInt(v) => format!("{v}"),
UInt(v) => format!("{v}"),
UBigInt(v) => format!("{v}"),
Json(v) => format!("\"{}\"", v),
VarBinary(_) => todo!(),
Decimal(_) => todo!(),
Blob(_) => todo!(),
MediumBlob(_) => todo!(),
}
}
pub fn to_string(&self) -> Result<String, Utf8Error> {
use Value::*;
match self {
Null(_) => Ok(String::new()),
VarChar(v) => Ok(v.to_string()),
Json(v) => Ok(v.to_string()),
NChar(v) => Ok(v.to_string()),
TinyInt(v) => Ok(format!("{v}")),
SmallInt(v) => Ok(format!("{v}")),
Int(v) => Ok(format!("{v}")),
BigInt(v) => Ok(format!("{v}")),
UTinyInt(v) => Ok(format!("{v}")),
USmallInt(v) => Ok(format!("{v}")),
UInt(v) => Ok(format!("{v}")),
UBigInt(v) => Ok(format!("{v}")),
Float(v) => Ok(format!("{v}")),
Double(v) => Ok(format!("{v}")),
Timestamp(v) => Ok(v.to_datetime_with_tz().to_rfc3339()),
_ => unreachable!("un supported type to string"),
}
}
pub fn to_json_value(&self) -> serde_json::Value {
use Value::*;
match self {
Null(_) => serde_json::Value::Null,
Bool(v) => serde_json::Value::Bool(*v),
TinyInt(v) => serde_json::Value::Number(serde_json::Number::from(*v)),
SmallInt(v) => serde_json::Value::Number(serde_json::Number::from(*v)),
Int(v) => serde_json::Value::Number(serde_json::Number::from(*v)),
BigInt(v) => serde_json::Value::Number(serde_json::Number::from(*v)),
UTinyInt(v) => serde_json::Value::Number(serde_json::Number::from(*v)),
USmallInt(v) => serde_json::Value::Number(serde_json::Number::from(*v)),
UInt(v) => serde_json::Value::Number(serde_json::Number::from(*v)),
UBigInt(v) => serde_json::Value::Number(serde_json::Number::from(*v)),
Float(v) => serde_json::Value::Number(serde_json::Number::from_f64(*v as f64).unwrap()),
Double(v) => serde_json::Value::Number(serde_json::Number::from_f64(*v).unwrap()),
VarChar(v) => serde_json::Value::String(v.to_string()),
Timestamp(v) => serde_json::Value::Number(serde_json::Number::from(v.as_raw_i64())),
Json(v) => v.clone(),
NChar(str) => serde_json::Value::String(str.to_string()),
VarBinary(_) => todo!(),
Decimal(_) => todo!(),
Blob(_) => todo!(),
MediumBlob(_) => todo!(),
}
}
}
impl<'b> PartialEq<&Value> for BorrowedValue<'b> {
fn eq(&self, other: &&Value) -> bool {
self == *other
}
}
impl<'b> PartialEq<Value> for BorrowedValue<'b> {
fn eq(&self, other: &Value) -> bool {
match (self, other) {
(Self::Null(l0), Value::Null(r0)) => l0 == r0,
(Self::Bool(l0), Value::Bool(r0)) => l0 == r0,
(Self::TinyInt(l0), Value::TinyInt(r0)) => l0 == r0,
(Self::SmallInt(l0), Value::SmallInt(r0)) => l0 == r0,
(Self::Int(l0), Value::Int(r0)) => l0 == r0,
(Self::BigInt(l0), Value::BigInt(r0)) => l0 == r0,
(Self::Float(l0), Value::Float(r0)) => l0 == r0,
(Self::Double(l0), Value::Double(r0)) => l0 == r0,
(Self::VarChar(l0), Value::VarChar(r0)) => l0 == r0,
(Self::Timestamp(l0), Value::Timestamp(r0)) => l0 == r0,
(Self::NChar(l0), Value::NChar(r0)) => l0 == r0,
(Self::UTinyInt(l0), Value::UTinyInt(r0)) => l0 == r0,
(Self::USmallInt(l0), Value::USmallInt(r0)) => l0 == r0,
(Self::UInt(l0), Value::UInt(r0)) => l0 == r0,
(Self::UBigInt(l0), Value::UBigInt(r0)) => l0 == r0,
(Self::Json(l0), Value::Json(r0)) => l0.as_ref() == serde_json::to_vec(r0).unwrap(),
(Self::VarBinary(l0), Value::VarBinary(r0)) => l0 == r0,
(Self::Decimal(l0), Value::Decimal(r0)) => l0 == r0,
(Self::Blob(l0), Value::Blob(r0)) => l0 == r0,
(Self::MediumBlob(l0), Value::MediumBlob(r0)) => l0 == r0,
_ => false,
}
}
}
impl<'b> PartialEq<BorrowedValue<'b>> for Value {
fn eq(&self, other: &BorrowedValue<'b>) -> bool {
match (other, self) {
(BorrowedValue::Null(l0), Value::Null(r0)) => l0 == r0,
(BorrowedValue::Bool(l0), Value::Bool(r0)) => l0 == r0,
(BorrowedValue::TinyInt(l0), Value::TinyInt(r0)) => l0 == r0,
(BorrowedValue::SmallInt(l0), Value::SmallInt(r0)) => l0 == r0,
(BorrowedValue::Int(l0), Value::Int(r0)) => l0 == r0,
(BorrowedValue::BigInt(l0), Value::BigInt(r0)) => l0 == r0,
(BorrowedValue::Float(l0), Value::Float(r0)) => l0 == r0,
(BorrowedValue::Double(l0), Value::Double(r0)) => l0 == r0,
(BorrowedValue::VarChar(l0), Value::VarChar(r0)) => l0 == r0,
(BorrowedValue::Timestamp(l0), Value::Timestamp(r0)) => l0 == r0,
(BorrowedValue::NChar(l0), Value::NChar(r0)) => l0 == r0,
(BorrowedValue::UTinyInt(l0), Value::UTinyInt(r0)) => l0 == r0,
(BorrowedValue::USmallInt(l0), Value::USmallInt(r0)) => l0 == r0,
(BorrowedValue::UInt(l0), Value::UInt(r0)) => l0 == r0,
(BorrowedValue::UBigInt(l0), Value::UBigInt(r0)) => l0 == r0,
(BorrowedValue::Json(l0), Value::Json(r0)) => {
l0.as_ref() == serde_json::to_vec(r0).unwrap()
}
(BorrowedValue::VarBinary(l0), Value::VarBinary(r0)) => l0 == r0,
(BorrowedValue::Decimal(l0), Value::Decimal(r0)) => l0 == r0,
(BorrowedValue::Blob(l0), Value::Blob(r0)) => l0 == r0,
(BorrowedValue::MediumBlob(l0), Value::MediumBlob(r0)) => l0 == r0,
_ => false,
}
}
}
macro_rules! _impl_primitive_from {
($f:ident, $t:ident) => {
impl From<$f> for Value {
fn from(value: $f) -> Self {
Value::$t(value)
}
}
impl From<Option<$f>> for Value {
fn from(value: Option<$f>) -> Self {
match value {
Some(value) => Value::$t(value),
None => Value::Null(Ty::$t),
}
}
}
};
}
_impl_primitive_from!(bool, Bool);
_impl_primitive_from!(i8, TinyInt);
_impl_primitive_from!(i16, SmallInt);
_impl_primitive_from!(i32, Int);
_impl_primitive_from!(i64, BigInt);
_impl_primitive_from!(u8, UTinyInt);
_impl_primitive_from!(u16, USmallInt);
_impl_primitive_from!(u32, UInt);
_impl_primitive_from!(u64, UBigInt);
_impl_primitive_from!(f32, Float);
_impl_primitive_from!(f64, Double);
_impl_primitive_from!(Timestamp, Timestamp);
mod de;