async_graphql/types/external/
time_offset_date_time.rs1use time::{OffsetDateTime, UtcOffset, format_description::well_known::Rfc3339};
2
3use crate::{InputValueError, InputValueResult, Scalar, ScalarType, Value};
4
5#[Scalar(
12 internal,
13 name = "DateTime",
14 specified_by_url = "https://datatracker.ietf.org/doc/html/rfc3339"
15)]
16impl ScalarType for OffsetDateTime {
17 fn parse(value: Value) -> InputValueResult<Self> {
18 match &value {
19 Value::String(s) => Ok(Self::parse(s, &Rfc3339)?),
20 _ => Err(InputValueError::expected_type(value)),
21 }
22 }
23
24 fn to_value(&self) -> Value {
25 Value::String(
26 self.to_offset(UtcOffset::UTC)
27 .format(&Rfc3339)
28 .unwrap_or_else(|e| panic!("Failed to format `OffsetDateTime`: {}", e)),
29 )
30 }
31}
32
33#[cfg(test)]
34mod tests {
35 use time::{OffsetDateTime, macros::datetime};
36
37 use crate::{ScalarType, Value};
38
39 #[test]
40 fn test_offset_date_time_to_value() {
41 let cases = [
42 (
43 datetime!(2022-01-12 07:30:19.12345 +3:30),
44 "2022-01-12T04:00:19.12345Z",
45 ),
46 (datetime!(2022-01-12 07:30:19-0), "2022-01-12T07:30:19Z"),
47 ];
48 for (value, expected) in cases {
49 let value = value.to_value();
50
51 if let Value::String(s) = value {
52 assert_eq!(s, expected);
53 } else {
54 panic!(
55 "Unexpected Value type when formatting OffsetDateTime: {:?}",
56 value
57 );
58 }
59 }
60 }
61
62 #[test]
63 fn test_offset_date_time_parse() {
64 let cases = [
65 (
66 "2022-01-12T04:00:19.12345Z",
67 datetime!(2022-01-12 07:30:19.12345 +3:30),
68 ),
69 (
70 "2022-01-12T23:22:19.12345-00:00",
71 datetime!(2022-01-12 23:22:19.12345-0),
72 ),
73 ];
74 for (value, expected) in cases {
75 let value = Value::String(value.to_string());
76 let parsed = <OffsetDateTime as ScalarType>::parse(value).unwrap();
77 assert_eq!(parsed, expected);
78 }
79 }
80}