use super::{Plaintext, PlaintextNullVariant};
use chrono::{DateTime, NaiveDate, Utc};
use rust_decimal::Decimal;
macro_rules! impl_from {
($ty:ty, $variant:ident) => {
impl From<$ty> for Plaintext {
fn from(value: $ty) -> Self {
Plaintext::$variant(Some(value))
}
}
};
}
impl<T> From<Option<T>> for Plaintext
where
T: Into<Plaintext> + PlaintextNullVariant,
{
fn from(value: Option<T>) -> Self {
if let Some(value) = value {
value.into()
} else {
T::null()
}
}
}
impl From<&str> for Plaintext {
fn from(value: &str) -> Self {
value.to_string().into()
}
}
macro_rules! to_conversions_and_tests {
(impls => { $(($($value:expr),*) => $ty:ty => $variant:ident),* } extra_tests => { $($test_tokens:tt)* }) => {
$(
impl_from!($ty, $variant);
)*
#[allow(dead_code)]
fn exhaustive_check(value: Plaintext) {
match value {
$(
Plaintext::$variant(_) => {},
)*
}
}
#[cfg(test)]
mod tests {
use super::*;
$(
paste::paste! {
#[test]
fn [<test_to_ $variant:snake>]() {
$(
assert_eq!(
Plaintext::from($ty::from($value)),
Plaintext::$variant(Some($ty::from($value)))
);
)*
}
#[test]
fn [<test_to_ $variant:snake _option>]() {
$(
assert_eq!(
Plaintext::from(Some($ty::from($value))),
Plaintext::$variant(Some($ty::from($value)))
);
)*
}
#[test]
fn [<test_to_ $variant:snake _option_none>]() {
assert_eq!(
Plaintext::from(Option::<$ty>::None),
Plaintext::$variant(None)
);
}
}
)*
$($test_tokens)*
}
}
}
to_conversions_and_tests! {
impls => {
(10_i64, -10_i64) => i64 => BigInt,
(10_u64, 100_u64) => u64 => BigUInt,
(10_i32, -10_i32) => i32 => Int,
(10_i16, -10_i16) => i16 => SmallInt,
(0., -1., 100.) => f64 => Float,
(Decimal::new(10, 0), Decimal::new(-10, 0)) => Decimal => Decimal,
(NaiveDate::from_ymd_opt(2020, 1, 1).expect("Expected date to create")) => NaiveDate => NaiveDate,
(DateTime::<Utc>::from_timestamp(1000, 0).expect("Expected timestamp to create")) => DateTime::<Utc> => Timestamp,
(true, false) => bool => Boolean,
("hello", "") => String => Utf8Str,
(serde_json::json!({"hello": "world"}), serde_json::json!({})) => serde_json::Value => JsonB
}
extra_tests => {
#[test]
fn test_to_utf8_str_from_str() {
assert_eq!(
Plaintext::from("hello"),
Plaintext::Utf8Str(Some("hello".to_string()))
);
assert_eq!(
Plaintext::from(Some("hello")),
Plaintext::Utf8Str(Some("hello".to_string()))
);
assert_eq!(
Plaintext::from(Option::<&str>::None),
Plaintext::Utf8Str(None)
);
}
}
}