use crate::{Result, driver, stmt};
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum Type {
Boolean,
Integer(u8),
UnsignedInteger(u8),
Text,
VarChar(u64),
Uuid,
Numeric(Option<(u32, u32)>),
Blob,
Binary(u8),
Timestamp(u8),
Date,
Time(u8),
DateTime(u8),
Custom(String),
}
impl Type {
pub fn from_app(
ty: &stmt::Type,
hint: Option<&Type>,
db: &driver::StorageTypes,
) -> Result<Type> {
match hint {
Some(ty) => Ok(ty.clone()),
None => match ty {
stmt::Type::Bool => Ok(Type::Boolean),
stmt::Type::I8 => Ok(Type::Integer(1)),
stmt::Type::I16 => Ok(Type::Integer(2)),
stmt::Type::I32 => Ok(Type::Integer(4)),
stmt::Type::I64 => Ok(Type::Integer(8)),
stmt::Type::U8 => Ok(Type::UnsignedInteger(1)),
stmt::Type::U16 => Ok(Type::UnsignedInteger(2)),
stmt::Type::U32 => Ok(Type::UnsignedInteger(4)),
stmt::Type::U64 => Ok(Type::UnsignedInteger(8)),
stmt::Type::String => Ok(db.default_string_type.clone()),
stmt::Type::Uuid => Ok(db.default_uuid_type.clone()),
stmt::Type::Bytes => Ok(db.default_bytes_type.clone()),
#[cfg(feature = "rust_decimal")]
stmt::Type::Decimal => Ok(db.default_decimal_type.clone()),
#[cfg(feature = "bigdecimal")]
stmt::Type::BigDecimal => Ok(db.default_bigdecimal_type.clone()),
#[cfg(feature = "jiff")]
stmt::Type::Timestamp => Ok(db.default_timestamp_type.clone()),
#[cfg(feature = "jiff")]
stmt::Type::Zoned => Ok(db.default_zoned_type.clone()),
#[cfg(feature = "jiff")]
stmt::Type::Date => Ok(db.default_date_type.clone()),
#[cfg(feature = "jiff")]
stmt::Type::Time => Ok(db.default_time_type.clone()),
#[cfg(feature = "jiff")]
stmt::Type::DateTime => Ok(db.default_datetime_type.clone()),
_ => Err(crate::Error::unsupported_feature(format!(
"type {:?} is not supported by this database",
ty
))),
},
}
}
pub fn bridge_type(&self, ty: &stmt::Type) -> stmt::Type {
match (self, ty) {
(Self::Blob | Self::Binary(_), stmt::Type::Uuid) => stmt::Type::Bytes,
(Self::Text | Self::VarChar(_), _) => stmt::Type::String,
#[cfg(feature = "jiff")]
(Self::Timestamp(_) | Self::DateTime(_), stmt::Type::Zoned) => stmt::Type::Timestamp,
_ => ty.clone(),
}
}
pub(crate) fn verify(&self, db: &driver::Capability) -> Result<()> {
match *self {
Type::VarChar(size) => match db.storage_types.varchar {
Some(max) if size > max => Err(crate::Error::unsupported_feature(format!(
"VARCHAR({}) exceeds database maximum of {}",
size, max
))),
None => Err(crate::Error::unsupported_feature(
"VARCHAR type is not supported by this database",
)),
_ => Ok(()),
},
_ => Ok(()),
}
}
}