use std::fmt::Debug;
use std::marker::PhantomData;
use rstest::rstest;
use serde::{Deserialize, Serialize};
use serde_test2::Configure;
use time::Month::*;
use time::Weekday::*;
use time::macros::{date, datetime, time};
use time::{Date, Duration, Month, OffsetDateTime, PrimitiveDateTime, Time, Weekday};
enum Format {
Compact,
Readable,
}
use Format::*;
#[rstest]
#[case(Monday.compact(), "1")]
#[case(Monday.readable(), r#""Monday""#)]
#[case(March.compact(), "3")]
#[case(March.readable(), r#""March""#)]
#[case(time!(12:40:20).compact(), "[12,40,20,0]")]
#[case(time!(12:40:20).readable(), r#""12:40:20.0""#)]
#[case(datetime!(2022-05-20 12:40:20).compact(), "[2022,140,12,40,20,0]")]
#[case(datetime!(2022-05-20 12:40:20).readable(), r#""2022-05-20 12:40:20.0""#)]
#[case(datetime!(2022-05-20 12:40:20 UTC).compact(), "[2022,140,12,40,20,0,0,0,0]")]
#[case(datetime!(2022-05-20 12:40:20 UTC).readable(), r#""2022-05-20 12:40:20.0 +00:00:00""#)]
#[case(Duration::new(50, 0).compact(), "[50,0]")]
#[case(Duration::new(50, 0).readable(), r#""50.000000000""#)]
#[case(date!(2022-04-05).compact(), "[2022,95]")]
#[case(date!(2022-04-05).readable(), r#""2022-04-05""#)]
fn serialize<T>(#[case] value: T, #[case] expected: &str)
where
T: Serialize,
{
let mut buf: Vec<u8> = Vec::new();
let mut ser = serde_json::Serializer::new(&mut buf);
value.serialize(&mut ser).expect("serialization failed");
assert_eq!(String::from_utf8(buf).as_deref(), Ok(expected));
}
#[rstest]
#[case(PhantomData::<Weekday>, Compact, "1", Monday)]
#[case(PhantomData::<Weekday>, Readable, "1", Monday)]
#[case(PhantomData::<Weekday>, Readable, r#""Monday""#, Monday)]
#[case(PhantomData::<Month>, Compact, "3", March)]
#[case(PhantomData::<Month>, Readable, "3", March)]
#[case(PhantomData::<Month>, Readable, r#""March""#, March)]
#[case(PhantomData::<Time>, Compact, "[12,40,20,0]", time!(12:40:20))]
#[case(PhantomData::<Time>, Readable, "[12,40,20,0]", time!(12:40:20))]
#[case(PhantomData::<Time>, Readable, r#""12:40:20.0""#, time!(12:40:20))]
#[case(
PhantomData::<PrimitiveDateTime>,
Compact,
"[2022,140,12,40,20,0]",
datetime!(2022-05-20 12:40:20),
)]
#[case(
PhantomData::<PrimitiveDateTime>,
Readable,
"[2022,140,12,40,20,0]",
datetime!(2022-05-20 12:40:20),
)]
#[case(
PhantomData::<PrimitiveDateTime>,
Readable,
r#""2022-05-20 12:40:20.0""#,
datetime!(2022-05-20 12:40:20),
)]
#[case(
PhantomData::<OffsetDateTime>,
Compact,
"[2022,140,12,40,20,0,0,0,0]",
datetime!(2022-05-20 12:40:20 UTC),
)]
#[case(
PhantomData::<OffsetDateTime>,
Readable,
"[2022,140,12,40,20,0,0,0,0]",
datetime!(2022-05-20 12:40:20 UTC),
)]
#[case(
PhantomData::<OffsetDateTime>,
Readable,
r#""2022-05-20 12:40:20.0 +00:00:00""#,
datetime!(2022-05-20 12:40:20 UTC),
)]
#[case(PhantomData::<Duration>, Compact, "[50,0]", Duration::new(50, 0))]
#[case(PhantomData::<Duration>, Readable, "[50,0]", Duration::new(50, 0))]
#[case(PhantomData::<Duration>, Readable, r#""50.000000000""#, Duration::new(50, 0))]
#[case(PhantomData::<Date>, Compact, "[2022,95]", date!(2022-04-05))]
#[case(PhantomData::<Date>, Readable, "[2022,95]", date!(2022-04-05))]
#[case(PhantomData::<Date>, Readable, r#""2022-04-05""#, date!(2022-04-05))]
fn deserialize<T>(
#[case] _type: PhantomData<T>,
#[case] format: Format,
#[case] value: &str,
#[case] expected: T,
) where
T: Debug + PartialEq + for<'de> Deserialize<'de>,
{
let mut de = serde_json::Deserializer::from_str(value);
let value = match format {
Compact => T::deserialize((&mut de).compact()),
Readable => T::deserialize((&mut de).readable()),
}
.expect("deserialization failed");
assert_eq!(value, expected);
}