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