use std::borrow::Cow;
use crate::{ColumnType, CommonSqlQueryBuilder, QueryBuilder, RcOrArc, StringLen};
#[cfg(test)]
mod tests;
pub mod prelude;
#[allow(unused_imports)]
use prelude::*;
#[cfg(feature = "hashable-value")]
mod hashable_value;
mod value_class;
pub use value_class::*;
mod value_tuple;
pub use value_tuple::*;
#[cfg(feature = "with-json")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-json")))]
mod with_json;
#[cfg(feature = "with-json")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-json")))]
pub use with_json::sea_value_to_json_value;
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
mod with_chrono;
#[cfg(feature = "with-time")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
pub mod time_format;
#[cfg(feature = "with-time")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
mod with_time;
#[cfg(feature = "with-jiff")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
pub mod with_jiff;
#[cfg(feature = "with-rust_decimal")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-rust_decimal")))]
mod with_rust_decimal;
#[cfg(feature = "with-bigdecimal")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-bigdecimal")))]
mod with_bigdecimal;
#[cfg(feature = "with-uuid")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-uuid")))]
mod with_uuid;
#[cfg(feature = "with-ipnetwork")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-ipnetwork")))]
mod with_ipnetwork;
#[cfg(feature = "with-mac_address")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-mac_address")))]
mod with_mac_address;
#[cfg(feature = "postgres-array")]
#[cfg_attr(docsrs, doc(cfg(feature = "postgres-array")))]
pub mod postgres_array;
#[cfg(feature = "postgres-vector")]
#[cfg_attr(docsrs, doc(cfg(feature = "postgres-vector")))]
mod postgres_vector;
#[cfg(feature = "postgres-range")]
#[cfg_attr(docsrs, doc(cfg(feature = "postgres-range")))]
mod postgres_range;
#[cfg(all(test, feature = "serde", feature = "with-json"))]
mod serde_tests;
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum ArrayType {
Bool,
TinyInt,
SmallInt,
Int,
BigInt,
TinyUnsigned,
SmallUnsigned,
Unsigned,
BigUnsigned,
Float,
Double,
String,
#[cfg(feature = "backend-postgres")]
#[cfg_attr(docsrs, doc(cfg(feature = "backend-postgres")))]
Enum(Box<EnumTypeName>),
Char,
Bytes,
#[cfg(feature = "with-json")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-json")))]
Json,
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
ChronoDate,
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
ChronoTime,
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
ChronoDateTime,
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
ChronoDateTimeUtc,
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
ChronoDateTimeLocal,
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
ChronoDateTimeWithTimeZone,
#[cfg(feature = "with-time")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
TimeDate,
#[cfg(feature = "with-time")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
TimeTime,
#[cfg(feature = "with-time")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
TimeDateTime,
#[cfg(feature = "with-time")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
TimeDateTimeWithTimeZone,
#[cfg(feature = "with-jiff")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
JiffDate,
#[cfg(feature = "with-jiff")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
JiffTime,
#[cfg(feature = "with-jiff")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
JiffDateTime,
#[cfg(feature = "with-jiff")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
JiffTimestamp,
#[cfg(feature = "with-uuid")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-uuid")))]
Uuid,
#[cfg(feature = "with-rust_decimal")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-rust_decimal")))]
Decimal,
#[cfg(feature = "with-bigdecimal")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-bigdecimal")))]
BigDecimal,
#[cfg(feature = "with-ipnetwork")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-ipnetwork")))]
IpNetwork,
#[cfg(feature = "with-mac_address")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-mac_address")))]
MacAddress,
#[cfg(feature = "postgres-range")]
#[cfg_attr(docsrs, doc(cfg(feature = "postgres-range")))]
Range,
}
pub type EnumTypeName = RcOrArc<str>;
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Enum {
pub type_name: EnumTypeName,
pub value: Cow<'static, str>,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum OptionEnum {
Some(Box<Enum>),
None(EnumTypeName),
}
impl OptionEnum {
pub fn is_some(&self) -> bool {
matches!(*self, OptionEnum::Some(_))
}
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(not(feature = "hashable-value"), derive(PartialEq))]
pub enum Value {
Bool(Option<bool>),
TinyInt(Option<i8>),
SmallInt(Option<i16>),
Int(Option<i32>),
BigInt(Option<i64>),
TinyUnsigned(Option<u8>),
SmallUnsigned(Option<u16>),
Unsigned(Option<u32>),
BigUnsigned(Option<u64>),
Float(Option<f32>),
Double(Option<f64>),
String(Option<String>),
Enum(OptionEnum),
Char(Option<char>),
#[allow(clippy::box_collection)]
Bytes(Option<Vec<u8>>),
#[cfg(feature = "with-json")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-json")))]
Json(Option<Box<Json>>),
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
ChronoDate(Option<NaiveDate>),
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
ChronoTime(Option<NaiveTime>),
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
ChronoDateTime(Option<NaiveDateTime>),
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
ChronoDateTimeUtc(Option<DateTime<Utc>>),
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
ChronoDateTimeLocal(Option<DateTime<Local>>),
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
ChronoDateTimeWithTimeZone(Option<DateTime<FixedOffset>>),
#[cfg(feature = "with-time")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
TimeDate(Option<time::Date>),
#[cfg(feature = "with-time")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
TimeTime(Option<time::Time>),
#[cfg(feature = "with-time")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
TimeDateTime(Option<PrimitiveDateTime>),
#[cfg(feature = "with-time")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
TimeDateTimeWithTimeZone(Option<OffsetDateTime>),
#[cfg(feature = "with-jiff")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
JiffDate(Option<jiff::civil::Date>),
#[cfg(feature = "with-jiff")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
JiffTime(Option<jiff::civil::Time>),
#[cfg(feature = "with-jiff")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
JiffDateTime(Option<Box<jiff::civil::DateTime>>),
#[cfg(feature = "with-jiff")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
JiffTimestamp(Option<Box<Timestamp>>),
#[cfg(feature = "with-uuid")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-uuid")))]
Uuid(Option<Uuid>),
#[cfg(feature = "with-rust_decimal")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-rust_decimal")))]
Decimal(Option<Decimal>),
#[cfg(feature = "with-bigdecimal")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-bigdecimal")))]
BigDecimal(Option<Box<BigDecimal>>),
#[cfg(feature = "postgres-array")]
#[cfg_attr(docsrs, doc(cfg(feature = "postgres-array")))]
Array(ArrayType, Option<Box<Vec<Value>>>),
#[cfg(feature = "postgres-vector")]
#[cfg_attr(docsrs, doc(cfg(feature = "postgres-vector")))]
Vector(Option<pgvector::Vector>),
#[cfg(feature = "with-ipnetwork")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-ipnetwork")))]
IpNetwork(Option<IpNetwork>),
#[cfg(feature = "with-mac_address")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-mac_address")))]
MacAddress(Option<MacAddress>),
#[cfg(feature = "postgres-range")]
#[cfg_attr(docsrs, doc(cfg(feature = "postgres-range")))]
Range(Option<Box<RangeType>>),
}
pub const VALUE_SIZE: usize = check_value_size();
const MAX_VALUE_SIZE: usize = 32;
const fn check_value_size() -> usize {
if std::mem::size_of::<Value>() > MAX_VALUE_SIZE {
panic!(
"the size of Value shouldn't be greater than the expected MAX_VALUE_SIZE (32 bytes by default)"
)
}
std::mem::size_of::<Value>()
}
impl Value {
pub fn unwrap<T>(self) -> T
where
T: ValueType,
{
T::unwrap(self)
}
pub fn expect<T>(self, msg: &str) -> T
where
T: ValueType,
{
T::expect(self, msg)
}
pub fn as_null(&self) -> Self {
match self {
Self::Bool(_) => Self::Bool(None),
Self::TinyInt(_) => Self::TinyInt(None),
Self::SmallInt(_) => Self::SmallInt(None),
Self::Int(_) => Self::Int(None),
Self::BigInt(_) => Self::BigInt(None),
Self::TinyUnsigned(_) => Self::TinyUnsigned(None),
Self::SmallUnsigned(_) => Self::SmallUnsigned(None),
Self::Unsigned(_) => Self::Unsigned(None),
Self::BigUnsigned(_) => Self::BigUnsigned(None),
Self::Float(_) => Self::Float(None),
Self::Double(_) => Self::Double(None),
Self::String(_) => Self::String(None),
Self::Enum(OptionEnum::Some(v)) => Self::Enum(OptionEnum::None(v.type_name.clone())),
Self::Enum(OptionEnum::None(type_name)) => {
Self::Enum(OptionEnum::None(type_name.clone()))
}
Self::Char(_) => Self::Char(None),
Self::Bytes(_) => Self::Bytes(None),
#[cfg(feature = "with-json")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-json")))]
Self::Json(_) => Self::Json(None),
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
Self::ChronoDate(_) => Self::ChronoDate(None),
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
Self::ChronoTime(_) => Self::ChronoTime(None),
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
Self::ChronoDateTime(_) => Self::ChronoDateTime(None),
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
Self::ChronoDateTimeUtc(_) => Self::ChronoDateTimeUtc(None),
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
Self::ChronoDateTimeLocal(_) => Self::ChronoDateTimeLocal(None),
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
Self::ChronoDateTimeWithTimeZone(_) => Self::ChronoDateTimeWithTimeZone(None),
#[cfg(feature = "with-time")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
Self::TimeDate(_) => Self::TimeDate(None),
#[cfg(feature = "with-time")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
Self::TimeTime(_) => Self::TimeTime(None),
#[cfg(feature = "with-time")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
Self::TimeDateTime(_) => Self::TimeDateTime(None),
#[cfg(feature = "with-time")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
Self::TimeDateTimeWithTimeZone(_) => Self::TimeDateTimeWithTimeZone(None),
#[cfg(feature = "with-jiff")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
Self::JiffDate(_) => Self::JiffDate(None),
#[cfg(feature = "with-jiff")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
Self::JiffTime(_) => Self::JiffTime(None),
#[cfg(feature = "with-jiff")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
Self::JiffDateTime(_) => Self::JiffDateTime(None),
#[cfg(feature = "with-jiff")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
Self::JiffTimestamp(_) => Self::JiffTimestamp(None),
#[cfg(feature = "with-uuid")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-uuid")))]
Self::Uuid(_) => Self::Uuid(None),
#[cfg(feature = "with-rust_decimal")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-rust_decimal")))]
Self::Decimal(_) => Self::Decimal(None),
#[cfg(feature = "with-bigdecimal")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-bigdecimal")))]
Self::BigDecimal(_) => Self::BigDecimal(None),
#[cfg(feature = "postgres-array")]
#[cfg_attr(docsrs, doc(cfg(feature = "postgres-array")))]
Self::Array(ty, _) => Self::Array(ty.clone(), None),
#[cfg(feature = "postgres-vector")]
#[cfg_attr(docsrs, doc(cfg(feature = "postgres-vector")))]
Self::Vector(_) => Self::Vector(None),
#[cfg(feature = "with-ipnetwork")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-ipnetwork")))]
Self::IpNetwork(_) => Self::IpNetwork(None),
#[cfg(feature = "with-mac_address")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-mac_address")))]
Self::MacAddress(_) => Self::MacAddress(None),
#[cfg(feature = "postgres-range")]
#[cfg_attr(docsrs, doc(cfg(feature = "postgres-range")))]
Self::Range(_) => Self::Range(None),
}
}
pub fn is_some(&self) -> bool {
match self {
Self::Bool(v) => v.is_some(),
Self::TinyInt(v) => v.is_some(),
Self::SmallInt(v) => v.is_some(),
Self::Int(v) => v.is_some(),
Self::BigInt(v) => v.is_some(),
Self::TinyUnsigned(v) => v.is_some(),
Self::SmallUnsigned(v) => v.is_some(),
Self::Unsigned(v) => v.is_some(),
Self::BigUnsigned(v) => v.is_some(),
Self::Float(v) => v.is_some(),
Self::Double(v) => v.is_some(),
Self::String(v) => v.is_some(),
Self::Enum(v) => v.is_some(),
Self::Char(v) => v.is_some(),
Self::Bytes(v) => v.is_some(),
#[cfg(feature = "with-json")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-json")))]
Self::Json(v) => v.is_some(),
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
Self::ChronoDate(v) => v.is_some(),
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
Self::ChronoTime(v) => v.is_some(),
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
Self::ChronoDateTime(v) => v.is_some(),
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
Self::ChronoDateTimeUtc(v) => v.is_some(),
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
Self::ChronoDateTimeLocal(v) => v.is_some(),
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
Self::ChronoDateTimeWithTimeZone(v) => v.is_some(),
#[cfg(feature = "with-time")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
Self::TimeDate(v) => v.is_some(),
#[cfg(feature = "with-time")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
Self::TimeTime(v) => v.is_some(),
#[cfg(feature = "with-time")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
Self::TimeDateTime(v) => v.is_some(),
#[cfg(feature = "with-time")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
Self::TimeDateTimeWithTimeZone(v) => v.is_some(),
#[cfg(feature = "with-jiff")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
Self::JiffDate(v) => v.is_some(),
#[cfg(feature = "with-jiff")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
Self::JiffTime(v) => v.is_some(),
#[cfg(feature = "with-jiff")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
Self::JiffDateTime(v) => v.is_some(),
#[cfg(feature = "with-jiff")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
Self::JiffTimestamp(v) => v.is_some(),
#[cfg(feature = "with-uuid")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-uuid")))]
Self::Uuid(v) => v.is_some(),
#[cfg(feature = "with-rust_decimal")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-rust_decimal")))]
Self::Decimal(v) => v.is_some(),
#[cfg(feature = "with-bigdecimal")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-bigdecimal")))]
Self::BigDecimal(v) => v.is_some(),
#[cfg(feature = "postgres-array")]
#[cfg_attr(docsrs, doc(cfg(feature = "postgres-array")))]
Self::Array(_, v) => v.is_some(),
#[cfg(feature = "postgres-vector")]
#[cfg_attr(docsrs, doc(cfg(feature = "postgres-vector")))]
Self::Vector(v) => v.is_some(),
#[cfg(feature = "with-ipnetwork")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-ipnetwork")))]
Self::IpNetwork(v) => v.is_some(),
#[cfg(feature = "with-mac_address")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-mac_address")))]
Self::MacAddress(v) => v.is_some(),
#[cfg(feature = "postgres-range")]
#[cfg_attr(docsrs, doc(cfg(feature = "postgres-range")))]
Self::Range(v) => v.is_some(),
}
}
pub fn dummy_value(&self) -> Self {
match self {
Self::Bool(_) => Self::Bool(Some(Default::default())),
Self::TinyInt(_) => Self::TinyInt(Some(Default::default())),
Self::SmallInt(_) => Self::SmallInt(Some(Default::default())),
Self::Int(_) => Self::Int(Some(Default::default())),
Self::BigInt(_) => Self::BigInt(Some(Default::default())),
Self::TinyUnsigned(_) => Self::TinyUnsigned(Some(Default::default())),
Self::SmallUnsigned(_) => Self::SmallUnsigned(Some(Default::default())),
Self::Unsigned(_) => Self::Unsigned(Some(Default::default())),
Self::BigUnsigned(_) => Self::BigUnsigned(Some(Default::default())),
Self::Float(_) => Self::Float(Some(Default::default())),
Self::Double(_) => Self::Double(Some(Default::default())),
Self::String(_) => Self::String(Some(Default::default())),
Self::Enum(v) => {
let type_name = match v {
OptionEnum::Some(v) => v.type_name.clone(),
OptionEnum::None(type_name) => type_name.clone(),
};
Self::Enum(OptionEnum::Some(Box::new(Enum {
type_name,
value: Cow::Borrowed(""),
})))
}
Self::Char(_) => Self::Char(Some(Default::default())),
Self::Bytes(_) => Self::Bytes(Some(Default::default())),
#[cfg(feature = "with-json")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-json")))]
Self::Json(_) => Self::Json(Some(Default::default())),
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
Self::ChronoDate(_) => Self::ChronoDate(Some(Default::default())),
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
Self::ChronoTime(_) => Self::ChronoTime(Some(Default::default())),
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
Self::ChronoDateTime(_) => Self::ChronoDateTime(Some(Default::default())),
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
Self::ChronoDateTimeUtc(_) => Self::ChronoDateTimeUtc(Some(Default::default())),
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
Self::ChronoDateTimeLocal(_) => Self::ChronoDateTimeLocal(Some(Default::default())),
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
Self::ChronoDateTimeWithTimeZone(_) => {
Self::ChronoDateTimeWithTimeZone(Some(Default::default()))
}
#[cfg(feature = "with-time")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
Self::TimeDate(_) => Self::TimeDate(Some(time::Date::MIN)),
#[cfg(feature = "with-time")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
Self::TimeTime(_) => Self::TimeTime(Some(time::Time::MIDNIGHT)),
#[cfg(feature = "with-time")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
Self::TimeDateTime(_) => Self::TimeDateTime(Some(PrimitiveDateTime::MIN)),
#[cfg(feature = "with-time")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
Self::TimeDateTimeWithTimeZone(_) => {
Self::TimeDateTimeWithTimeZone(Some(OffsetDateTime::UNIX_EPOCH))
}
#[cfg(feature = "with-jiff")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
Self::JiffDate(_) => Self::JiffDate(Some(jiff::civil::date(1970, 1, 1))),
#[cfg(feature = "with-jiff")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
Self::JiffTime(_) => Self::JiffTime(Some(jiff::civil::time(0, 0, 0, 0))),
#[cfg(feature = "with-jiff")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
Self::JiffDateTime(_) => {
Self::JiffDateTime(Some(jiff::civil::date(1970, 1, 1).at(0, 0, 0, 0).into()))
}
#[cfg(feature = "with-jiff")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
Self::JiffTimestamp(_) => Self::JiffTimestamp(Some(Timestamp::UNIX_EPOCH.into())),
#[cfg(feature = "with-uuid")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-uuid")))]
Self::Uuid(_) => Self::Uuid(Some(Default::default())),
#[cfg(feature = "with-rust_decimal")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-rust_decimal")))]
Self::Decimal(_) => Self::Decimal(Some(Default::default())),
#[cfg(feature = "with-bigdecimal")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-bigdecimal")))]
Self::BigDecimal(_) => Self::BigDecimal(Some(Default::default())),
#[cfg(feature = "postgres-array")]
#[cfg_attr(docsrs, doc(cfg(feature = "postgres-array")))]
Self::Array(ty, _) => Self::Array(ty.clone(), Some(Default::default())),
#[cfg(feature = "postgres-vector")]
#[cfg_attr(docsrs, doc(cfg(feature = "postgres-vector")))]
Self::Vector(_) => Self::Vector(Some(vec![].into())),
#[cfg(feature = "with-ipnetwork")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-ipnetwork")))]
Self::IpNetwork(_) => Self::IpNetwork(Some("0.0.0.0".parse().unwrap())),
#[cfg(feature = "with-mac_address")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-mac_address")))]
Self::MacAddress(_) => Self::MacAddress(Some(Default::default())),
#[cfg(feature = "postgres-range")]
#[cfg_attr(docsrs, doc(cfg(feature = "postgres-range")))]
Self::Range(_) => Self::Range(Some(Default::default())),
}
}
pub fn array_type(&self) -> ArrayType {
#[allow(unused_imports)]
use std::ops::Deref;
fn array_type_of<V: ValueType>(_: &Option<V>) -> ArrayType {
V::array_type()
}
#[allow(dead_code)]
fn array_type_of_ref<V: ValueType>(_: Option<&V>) -> ArrayType {
V::array_type()
}
match self {
Self::Bool(v) => array_type_of(v),
Self::TinyInt(v) => array_type_of(v),
Self::SmallInt(v) => array_type_of(v),
Self::Int(v) => array_type_of(v),
Self::BigInt(v) => array_type_of(v),
Self::TinyUnsigned(v) => array_type_of(v),
Self::SmallUnsigned(v) => array_type_of(v),
Self::Unsigned(v) => array_type_of(v),
Self::BigUnsigned(v) => array_type_of(v),
Self::Float(v) => array_type_of(v),
Self::Double(v) => array_type_of(v),
Self::String(v) => array_type_of(v),
#[cfg(feature = "backend-postgres")]
Self::Enum(v) => ArrayType::Enum(Box::new(match v {
OptionEnum::Some(v) => v.type_name.clone(),
OptionEnum::None(type_name) => type_name.clone(),
})),
#[cfg(not(feature = "backend-postgres"))]
Self::Enum(_) => ArrayType::String,
Self::Char(v) => array_type_of(v),
Self::Bytes(v) => array_type_of(v),
#[cfg(feature = "with-json")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-json")))]
Self::Json(v) => array_type_of_ref(v.as_ref().map(|v| v.deref())),
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
Self::ChronoDate(v) => array_type_of(v),
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
Self::ChronoTime(v) => array_type_of(v),
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
Self::ChronoDateTime(v) => array_type_of(v),
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
Self::ChronoDateTimeUtc(v) => array_type_of(v),
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
Self::ChronoDateTimeLocal(v) => array_type_of(v),
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
Self::ChronoDateTimeWithTimeZone(v) => array_type_of(v),
#[cfg(feature = "with-time")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
Self::TimeDate(v) => array_type_of(v),
#[cfg(feature = "with-time")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
Self::TimeTime(v) => array_type_of(v),
#[cfg(feature = "with-time")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
Self::TimeDateTime(v) => array_type_of(v),
#[cfg(feature = "with-time")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
Self::TimeDateTimeWithTimeZone(v) => array_type_of(v),
#[cfg(feature = "with-jiff")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
Self::JiffDate(v) => array_type_of(v),
#[cfg(feature = "with-jiff")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
Self::JiffTime(v) => array_type_of(v),
#[cfg(feature = "with-jiff")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
Self::JiffDateTime(v) => array_type_of_ref(v.as_ref().map(|v| v.deref())),
#[cfg(feature = "with-jiff")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-jiff")))]
Self::JiffTimestamp(v) => array_type_of_ref(v.as_ref().map(|v| v.deref())),
#[cfg(feature = "with-uuid")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-uuid")))]
Self::Uuid(v) => array_type_of(v),
#[cfg(feature = "with-rust_decimal")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-rust_decimal")))]
Self::Decimal(v) => array_type_of(v),
#[cfg(feature = "with-bigdecimal")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-bigdecimal")))]
Self::BigDecimal(v) => array_type_of_ref(v.as_ref().map(|v| v.deref())),
#[cfg(feature = "postgres-array")]
#[cfg_attr(docsrs, doc(cfg(feature = "postgres-array")))]
Self::Array(v, _) => v.clone(),
#[cfg(feature = "postgres-vector")]
#[cfg_attr(docsrs, doc(cfg(feature = "postgres-vector")))]
Self::Vector(v) => array_type_of(v),
#[cfg(feature = "with-ipnetwork")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-ipnetwork")))]
Self::IpNetwork(v) => array_type_of(v),
#[cfg(feature = "with-mac_address")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-mac_address")))]
Self::MacAddress(v) => array_type_of(v),
#[cfg(feature = "postgres-range")]
#[cfg_attr(docsrs, doc(cfg(feature = "postgres-range")))]
Self::Range(v) => array_type_of_ref(v.as_ref().map(|v| v.deref())),
}
}
}
impl From<&[u8]> for Value {
fn from(x: &[u8]) -> Value {
Value::Bytes(Some(x.into()))
}
}
impl From<&str> for Value {
fn from(x: &str) -> Value {
Value::String(Some(x.to_owned()))
}
}
impl From<&String> for Value {
fn from(x: &String) -> Value {
Value::String(Some(x.clone()))
}
}
impl<T> From<Option<T>> for Value
where
T: Into<Value> + Nullable,
{
fn from(x: Option<T>) -> Value {
match x {
Some(v) => v.into(),
None => T::null(),
}
}
}
impl From<Cow<'_, str>> for Value {
fn from(x: Cow<'_, str>) -> Value {
x.into_owned().into()
}
}
impl From<Enum> for Value {
fn from(value: Enum) -> Value {
Value::Enum(OptionEnum::Some(Box::new(value)))
}
}
impl IntoIterator for Values {
type Item = Value;
type IntoIter = std::vec::IntoIter<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
impl std::fmt::Display for Value {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
CommonSqlQueryBuilder.write_value(f, self)
}
}
pub trait ValueType: Sized {
fn try_from(v: Value) -> Result<Self, ValueTypeErr>;
fn unwrap(v: Value) -> Self {
Self::try_from(v).unwrap()
}
fn expect(v: Value, msg: &str) -> Self {
Self::try_from(v).expect(msg)
}
fn is_option() -> bool {
false
}
fn type_name() -> String;
fn array_type() -> ArrayType;
fn column_type() -> ColumnType;
fn enum_type_name() -> Option<&'static str> {
None
}
}
impl<T> ValueType for Option<T>
where
T: ValueType + Nullable,
{
fn try_from(v: Value) -> Result<Self, ValueTypeErr> {
if v == T::null() {
Ok(None)
} else {
Ok(Some(T::try_from(v)?))
}
}
fn is_option() -> bool {
true
}
fn type_name() -> String {
format!("Option<{}>", T::type_name())
}
fn array_type() -> ArrayType {
T::array_type()
}
fn column_type() -> ColumnType {
T::column_type()
}
}
impl ValueType for Cow<'_, str> {
fn try_from(v: Value) -> Result<Self, ValueTypeErr> {
match v {
Value::String(Some(x)) => Ok((x).into()),
_ => Err(ValueTypeErr),
}
}
fn type_name() -> String {
"Cow<str>".into()
}
fn array_type() -> ArrayType {
ArrayType::String
}
fn column_type() -> ColumnType {
ColumnType::String(StringLen::None)
}
}
#[derive(Debug)]
pub struct ValueTypeErr;
impl std::error::Error for ValueTypeErr {}
impl std::fmt::Display for ValueTypeErr {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
f.write_str("Value type mismatch")
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct Values(pub Vec<Value>);
impl Values {
pub fn iter(&self) -> impl Iterator<Item = &Value> {
self.0.iter()
}
}
pub trait Nullable {
fn null() -> Value;
}
impl Nullable for &str {
fn null() -> Value {
Value::String(None)
}
}
impl Nullable for Enum {
fn null() -> Value {
Value::Enum(OptionEnum::None("".into()))
}
}
impl ValueType for Enum {
fn try_from(v: Value) -> Result<Self, ValueTypeErr> {
match v {
Value::Enum(OptionEnum::Some(v)) => Ok(*v),
_ => Err(ValueTypeErr),
}
}
fn type_name() -> String {
"Enum".into()
}
fn array_type() -> ArrayType {
ArrayType::String
}
fn column_type() -> ColumnType {
ColumnType::String(StringLen::None)
}
}
macro_rules! type_to_value {
( $type: ty, $name: ident, $col_type: expr ) => {
impl From<$type> for Value {
fn from(x: $type) -> Value {
Value::$name(Some(x))
}
}
impl Nullable for $type {
fn null() -> Value {
Value::$name(None)
}
}
impl ValueType for $type {
fn try_from(v: Value) -> Result<Self, ValueTypeErr> {
match v {
Value::$name(Some(x)) => Ok(x),
_ => Err(ValueTypeErr),
}
}
fn type_name() -> String {
stringify!($type).to_owned()
}
fn array_type() -> ArrayType {
ArrayType::$name
}
fn column_type() -> ColumnType {
use ColumnType::*;
$col_type
}
}
};
}
#[allow(unused_imports)]
use type_to_value;
type_to_value!(bool, Bool, Boolean);
type_to_value!(i8, TinyInt, TinyInteger);
type_to_value!(i16, SmallInt, SmallInteger);
type_to_value!(i32, Int, Integer);
type_to_value!(i64, BigInt, BigInteger);
type_to_value!(u8, TinyUnsigned, TinyUnsigned);
type_to_value!(u16, SmallUnsigned, SmallUnsigned);
type_to_value!(u32, Unsigned, Unsigned);
type_to_value!(u64, BigUnsigned, BigUnsigned);
type_to_value!(f32, Float, Float);
type_to_value!(f64, Double, Double);
type_to_value!(char, Char, Char(None));
type_to_value!(Vec<u8>, Bytes, VarBinary(StringLen::None));
type_to_value!(String, String, String(StringLen::None));
#[allow(unused_macros)]
macro_rules! type_to_box_value {
( $type: ty, $name: ident, $col_type: expr ) => {
impl From<$type> for Value {
fn from(x: $type) -> Value {
Value::$name(Some(Box::new(x)))
}
}
impl Nullable for $type {
fn null() -> Value {
Value::$name(None)
}
}
impl ValueType for $type {
fn try_from(v: Value) -> Result<Self, ValueTypeErr> {
match v {
Value::$name(Some(x)) => Ok(*x),
_ => Err(ValueTypeErr),
}
}
fn type_name() -> String {
stringify!($type).to_owned()
}
fn array_type() -> ArrayType {
ArrayType::$name
}
fn column_type() -> ColumnType {
use ColumnType::*;
$col_type
}
}
};
}
#[allow(unused_imports)]
use type_to_box_value;