use std::borrow::Cow;
use std::collections::HashMap;
use std::time::Duration;
#[cfg(feature = "big-number")]
use bigdecimal::BigDecimal;
#[cfg(feature = "chrono")]
use chrono::{
DateTime,
NaiveDate,
NaiveDateTime,
NaiveTime,
Utc,
};
#[cfg(feature = "big-number")]
use num_bigint::BigInt;
#[cfg(feature = "url")]
use url::Url;
use super::data_convert_to::DataConvertTo;
use super::error::{
DataConversionError,
InvalidValueReason,
};
use super::options::DataConversionOptions;
use crate::datatype::DataType;
mod boolean;
mod duration;
mod numeric;
mod source;
mod string_source;
#[cfg(feature = "json")]
mod structured;
mod text;
#[derive(Debug, Clone, PartialEq)]
pub enum DataConverter<'a> {
Empty(DataType),
Bool(bool),
Char(char),
Int8(i8),
Int16(i16),
Int32(i32),
Int64(i64),
Int128(i128),
UInt8(u8),
UInt16(u16),
UInt32(u32),
UInt64(u64),
UInt128(u128),
Float32(f32),
Float64(f64),
#[cfg(feature = "big-number")]
BigInteger(Cow<'a, BigInt>),
#[cfg(feature = "big-number")]
BigDecimal(Cow<'a, BigDecimal>),
String(Cow<'a, str>),
#[cfg(feature = "chrono")]
Date(NaiveDate),
#[cfg(feature = "chrono")]
Time(NaiveTime),
#[cfg(feature = "chrono")]
DateTime(NaiveDateTime),
#[cfg(feature = "chrono")]
Instant(DateTime<Utc>),
Duration(Duration),
#[cfg(feature = "url")]
Url(Cow<'a, Url>),
StringMap(Cow<'a, HashMap<String, String>>),
#[cfg(feature = "json")]
Json(Cow<'a, serde_json::Value>),
}
impl DataConverter<'_> {
#[inline(always)]
pub fn to<T>(&self) -> Result<T, DataConversionError>
where
Self: DataConvertTo<T>,
{
self.to_with(DataConversionOptions::default_ref())
}
#[inline(always)]
pub fn to_with<T>(
&self,
options: &DataConversionOptions,
) -> Result<T, DataConversionError>
where
Self: DataConvertTo<T>,
{
<Self as DataConvertTo<T>>::convert(self, options)
}
#[inline]
pub const fn data_type(&self) -> DataType {
match self {
Self::Empty(data_type) => *data_type,
Self::Bool(_) => DataType::Bool,
Self::Char(_) => DataType::Char,
Self::Int8(_) => DataType::Int8,
Self::Int16(_) => DataType::Int16,
Self::Int32(_) => DataType::Int32,
Self::Int64(_) => DataType::Int64,
Self::Int128(_) => DataType::Int128,
Self::UInt8(_) => DataType::UInt8,
Self::UInt16(_) => DataType::UInt16,
Self::UInt32(_) => DataType::UInt32,
Self::UInt64(_) => DataType::UInt64,
Self::UInt128(_) => DataType::UInt128,
Self::Float32(_) => DataType::Float32,
Self::Float64(_) => DataType::Float64,
#[cfg(feature = "big-number")]
Self::BigInteger(_) => DataType::BigInteger,
#[cfg(feature = "big-number")]
Self::BigDecimal(_) => DataType::BigDecimal,
Self::String(_) => DataType::String,
#[cfg(feature = "chrono")]
Self::Date(_) => DataType::Date,
#[cfg(feature = "chrono")]
Self::Time(_) => DataType::Time,
#[cfg(feature = "chrono")]
Self::DateTime(_) => DataType::DateTime,
#[cfg(feature = "chrono")]
Self::Instant(_) => DataType::Instant,
Self::Duration(_) => DataType::Duration,
#[cfg(feature = "url")]
Self::Url(_) => DataType::Url,
Self::StringMap(_) => DataType::StringMap,
#[cfg(feature = "json")]
Self::Json(_) => DataType::Json,
}
}
#[inline(always)]
fn missing(&self, to: DataType) -> DataConversionError {
DataConversionError::Missing {
from: self.data_type(),
to,
}
}
#[inline(always)]
fn unsupported(&self, to: DataType) -> DataConversionError {
DataConversionError::Unsupported {
from: self.data_type(),
to,
}
}
#[inline(always)]
fn invalid(
&self,
to: DataType,
reason: InvalidValueReason,
) -> DataConversionError {
DataConversionError::InvalidValue {
from: self.data_type(),
to,
reason,
}
}
}