Skip to content

Commit f44c540

Browse files
Aegonekjhpratt
andauthored
Fix error when deserializing datatypes from number (#506)
Co-authored-by: Jacob Pratt <jacob@jhpratt.dev>
1 parent 738c75a commit f44c540

File tree

3 files changed

+153
-4
lines changed

3 files changed

+153
-4
lines changed

src/serde/visitor.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ impl<'a> de::Visitor<'a> for Visitor<Weekday> {
194194
}
195195
}
196196

197-
fn visit_u8<E: de::Error>(self, value: u8) -> Result<Weekday, E> {
197+
fn visit_u64<E: de::Error>(self, value: u64) -> Result<Weekday, E> {
198198
match value {
199199
1 => Ok(Weekday::Monday),
200200
2 => Ok(Weekday::Tuesday),
@@ -204,7 +204,7 @@ impl<'a> de::Visitor<'a> for Visitor<Weekday> {
204204
6 => Ok(Weekday::Saturday),
205205
7 => Ok(Weekday::Sunday),
206206
_ => Err(E::invalid_value(
207-
de::Unexpected::Unsigned(value.into()),
207+
de::Unexpected::Unsigned(value),
208208
&"a value in the range 1..=7",
209209
)),
210210
}
@@ -236,7 +236,7 @@ impl<'a> de::Visitor<'a> for Visitor<Month> {
236236
}
237237
}
238238

239-
fn visit_u8<E: de::Error>(self, value: u8) -> Result<Month, E> {
239+
fn visit_u64<E: de::Error>(self, value: u64) -> Result<Month, E> {
240240
match value {
241241
1 => Ok(Month::January),
242242
2 => Ok(Month::February),
@@ -251,7 +251,7 @@ impl<'a> de::Visitor<'a> for Visitor<Month> {
251251
11 => Ok(Month::November),
252252
12 => Ok(Month::December),
253253
_ => Err(E::invalid_value(
254-
de::Unexpected::Unsigned(value.into()),
254+
de::Unexpected::Unsigned(value),
255255
&"a value in the range 1..=12",
256256
)),
257257
}

tests/integration/serde/json.rs

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
use std::error::Error;
2+
3+
use serde::{Deserialize, Serialize};
4+
use serde_test::Configure;
5+
use time::macros::{date, datetime, time};
6+
use time::{Date, Duration, Month, OffsetDateTime, PrimitiveDateTime, Time, Weekday};
7+
8+
enum Format {
9+
Compact,
10+
Readable,
11+
}
12+
13+
use Format::*;
14+
15+
fn serialize<T: Serialize>(val: T) -> Result<String, Box<dyn Error>> {
16+
let mut buf: Vec<u8> = Vec::new();
17+
let mut ser = serde_json::Serializer::new(&mut buf);
18+
val.serialize(&mut ser)?;
19+
let str = String::from_utf8(buf)?;
20+
Ok(str)
21+
}
22+
23+
fn deserialize<'a, T: Deserialize<'a>>(from: &'a str, fmt: Format) -> serde_json::Result<T> {
24+
let mut de = serde_json::Deserializer::from_str(from);
25+
match fmt {
26+
Compact => T::deserialize((&mut de).compact()),
27+
Readable => T::deserialize((&mut de).readable()),
28+
}
29+
}
30+
31+
#[test]
32+
fn weekday_json() -> Result<(), Box<dyn Error>> {
33+
use Weekday::*;
34+
35+
assert_eq!(serialize(Monday.compact())?, "1");
36+
assert_eq!(deserialize::<Weekday>("1", Compact)?, Monday);
37+
38+
assert_eq!(serialize(Monday.readable())?, "\"Monday\"");
39+
assert_eq!(deserialize::<Weekday>("\"Monday\"", Readable)?, Monday);
40+
assert_eq!(deserialize::<Weekday>("1", Readable)?, Monday);
41+
42+
Ok(())
43+
}
44+
45+
#[test]
46+
fn month_json() -> Result<(), Box<dyn Error>> {
47+
use Month::*;
48+
49+
assert_eq!(serialize(March.compact())?, "3");
50+
assert_eq!(deserialize::<Month>("3", Compact)?, March);
51+
52+
assert_eq!(serialize(March.readable())?, "\"March\"");
53+
assert_eq!(deserialize::<Month>("\"March\"", Readable)?, March);
54+
assert_eq!(deserialize::<Month>("3", Readable)?, March);
55+
56+
Ok(())
57+
}
58+
59+
#[test]
60+
fn time_json() -> Result<(), Box<dyn Error>> {
61+
let time = time!(12:40:20);
62+
63+
assert_eq!(serialize(time.compact())?, "[12,40,20,0]");
64+
assert_eq!(deserialize::<Time>("[12,40,20,0]", Compact)?, time);
65+
66+
assert_eq!(serialize(time.readable())?, "\"12:40:20.0\"");
67+
assert_eq!(deserialize::<Time>("\"12:40:20.0\"", Readable)?, time);
68+
assert_eq!(deserialize::<Time>("[12,40,20,0]", Readable)?, time);
69+
70+
Ok(())
71+
}
72+
73+
#[test]
74+
fn primitive_datetime_json() -> Result<(), Box<dyn Error>> {
75+
let dt = datetime!(2022-05-20 12:40:20);
76+
77+
assert_eq!(serialize(dt.compact())?, "[2022,140,12,40,20,0]");
78+
assert_eq!(
79+
deserialize::<PrimitiveDateTime>("[2022,140,12,40,20,0]", Compact)?,
80+
dt
81+
);
82+
83+
assert_eq!(serialize(dt.readable())?, "\"2022-05-20 12:40:20.0\"");
84+
assert_eq!(
85+
deserialize::<PrimitiveDateTime>("\"2022-05-20 12:40:20.0\"", Readable)?,
86+
dt
87+
);
88+
assert_eq!(
89+
deserialize::<PrimitiveDateTime>("[2022,140,12,40,20,0]", Readable)?,
90+
dt
91+
);
92+
93+
Ok(())
94+
}
95+
96+
#[test]
97+
fn offset_datetime_json() -> Result<(), Box<dyn Error>> {
98+
let dt = datetime!(2022-05-20 12:40:20).assume_utc();
99+
100+
assert_eq!(serialize(dt.compact())?, "[2022,140,12,40,20,0,0,0,0]");
101+
assert_eq!(
102+
deserialize::<OffsetDateTime>("[2022,140,12,40,20,0,0,0,0]", Compact)?,
103+
dt
104+
);
105+
106+
assert_eq!(
107+
serialize(dt.readable())?,
108+
"\"2022-05-20 12:40:20.0 +00:00:00\""
109+
);
110+
assert_eq!(
111+
deserialize::<OffsetDateTime>("\"2022-05-20 12:40:20.0 +00:00:00\"", Readable)?,
112+
dt
113+
);
114+
assert_eq!(
115+
deserialize::<OffsetDateTime>("[2022,140,12,40,20,0,0,0,0]", Readable)?,
116+
dt
117+
);
118+
119+
Ok(())
120+
}
121+
122+
#[test]
123+
fn duration_json() -> Result<(), Box<dyn Error>> {
124+
let dur = Duration::new(50, 0);
125+
126+
assert_eq!(serialize(dur.compact())?, "[50,0]");
127+
assert_eq!(deserialize::<Duration>("[50,0]", Compact)?, dur);
128+
129+
assert_eq!(serialize(dur.readable())?, "\"50.000000000\"");
130+
assert_eq!(deserialize::<Duration>("\"50.000000000\"", Readable)?, dur);
131+
assert_eq!(deserialize::<Duration>("[50,0]", Readable)?, dur);
132+
133+
Ok(())
134+
}
135+
136+
#[test]
137+
fn date_json() -> Result<(), Box<dyn Error>> {
138+
let date = date!(2022 - 04 - 05);
139+
140+
assert_eq!(serialize(date.compact())?, "[2022,95]");
141+
assert_eq!(deserialize::<Date>("[2022,95]", Compact)?, date);
142+
143+
assert_eq!(serialize(date.readable())?, "\"2022-04-05\"");
144+
assert_eq!(deserialize::<Date>("\"2022-04-05\"", Readable)?, date);
145+
assert_eq!(deserialize::<Date>("[2022,95]", Readable)?, date);
146+
147+
Ok(())
148+
}

tests/integration/serde/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use time::{Date, Duration, Month, OffsetDateTime, PrimitiveDateTime, Time, UtcOf
44

55
mod error_conditions;
66
mod iso8601;
7+
mod json;
78
mod macros;
89
mod rfc2822;
910
mod rfc3339;

0 commit comments

Comments
 (0)