1use std::{fmt::Display, str::FromStr};
7
8#[derive(
9 Debug,
10 Clone,
11 PartialEq,
12 Eq,
13 PartialOrd,
14 Ord,
15 Hash,
16 derive_more::AsRef,
17 derive_more::From,
18 derive_more::Into,
19 serde_with::SerializeDisplay,
20 serde_with::DeserializeFromStr,
21)]
22#[cfg_attr(feature = "sea-orm", derive(sea_orm::DeriveValueType))]
23pub struct Date(time::Date);
24
25impl FromStr for Date {
26 type Err = time::error::Parse;
27
28 fn from_str(s: &str) -> Result<Self, Self::Err> {
29 use time::format_description::well_known::Iso8601;
30
31 Ok(Self(time::Date::parse(s, &Iso8601::DEFAULT)?))
32 }
33}
34
35impl Display for Date {
36 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
37 use time::format_description::well_known::Iso8601;
38
39 write!(f, "{}", self.0.format(&Iso8601::DATE).expect("valid date"))
40 }
41}
42
43#[cfg(test)]
44mod tests {
45 use super::Date;
46
47 use time::macros::date;
48
49 #[test]
50 fn from_str() {
51 let parsed: Date = "2025-01-07"
52 .parse()
53 .expect("string must be parseable as Date");
54 assert_eq!(parsed, Date(date!(2025 - 01 - 07)));
55 }
56
57 #[test]
58 fn to_string() {
59 let d = Date(date!(2025 - 01 - 07));
60
61 assert_eq!(d.to_string(), "2025-01-07".to_string());
62 }
63}
64
65#[cfg(test)]
66mod serde_tests {
67 use super::Date;
68
69 use pretty_assertions::assert_eq;
70 use serde_json::json;
71 use time::macros::date;
72
73 #[test]
74 fn serialize() {
75 assert_eq!(json!(Date(date!(2025 - 01 - 07))), json!("2025-01-07"));
76 }
77
78 #[test]
79 fn deserialize_good() {
80 let deserialized: Date =
81 serde_json::from_value(json!("2025-01-07")).expect("json must be parseable as Date");
82
83 assert_eq!(deserialized, Date(date!(2025 - 01 - 07)));
84 }
85
86 #[test]
87 fn deserialize_bad() {
88 assert!(serde_json::from_value::<Date>(json!("xyzabcd")).is_err());
89 assert!(serde_json::from_value::<Date>(json!(true)).is_err());
90 assert!(serde_json::from_value::<Date>(json!(123)).is_err());
91 }
92}