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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
use serde::Deserialize;
use serde::de::{self, Deserializer};
use std::fmt::Display;
use std::str::FromStr;
use url::Url;
use url_serde;
#[derive(Clone, Debug, Deserialize, PartialEq)]
pub struct XkcdResponse {
#[serde(deserialize_with = "de_from_str")]
pub month: u8,
pub num: u32,
pub link: String,
#[serde(deserialize_with = "de_from_str")]
pub year: u32,
pub news: String,
pub safe_title: String,
pub transcript: String,
pub alt: String,
#[serde(deserialize_with = "url_serde::deserialize")]
pub img: Url,
pub title: String,
#[serde(deserialize_with = "de_from_str")]
pub day: u8,
}
fn de_from_str<'de, D, T>(deserializer: D) -> Result<T, D::Error>
where D: Deserializer<'de>,
T: FromStr,
T::Err: Display,
{
let s = String::deserialize(deserializer)?;
T::from_str(&s).map_err(de::Error::custom)
}
#[cfg(test)]
mod tests {
use serde_json::from_str;
use super::XkcdResponse;
use super::super::parse_xkcd_response;
use url::Url;
use util::read_sample_data_from_path;
#[test]
fn test_parse_xkcd_response() {
let result = read_sample_data_from_path("tests/sample-data/example.json");
let response = from_str::<XkcdResponse>(result.as_str()).unwrap();
assert_eq!(response, XkcdResponse {
month: 9,
num: 1572,
link: "http://goo.gl/forms/pj0OhX6wfO".to_owned(),
year: 2015,
news: "".to_owned(),
safe_title: "xkcd Survey".to_owned(),
transcript: "Introducing the XKCD SURVEY! A search for weird correlations.\n\nNOTE: This survey is anonymous, but all responses will be posted publicly so people can play with the data.\n\nClick here to take the survey.\n\nhttp:\n\ngoo.gl\nforms\nlzZr7P9Qlm\n\nOr click here, or here. The whole comic is a link because I still haven't gotten the hang of HTML imagemaps.\n\n{{Title text: The xkcd Survey: Big Data for a Big Planet}}".to_owned(),
alt: "The xkcd Survey: Big Data for a Big Planet".to_owned(),
img: "http://imgs.xkcd.com/comics/xkcd_survey.png".to_owned().parse::<Url>().unwrap(),
title: "xkcd Survey".to_owned(),
day: 1,
});
}
#[test]
fn test_parse_xkcd_response_no_link() {
let result = read_sample_data_from_path("tests/sample-data/no-link.json");
let response = parse_xkcd_response::<XkcdResponse>(result.as_str()).unwrap();
assert_eq!(response, XkcdResponse {
month: 6,
num: 1698,
link: "".to_owned(),
year: 2016,
news: "".to_owned(),
safe_title: "Theft Quadrants".to_owned(),
transcript: "".to_owned(),
alt: "TinyURL was the most popular link shortener for long enough that it made it into a lot of printed publications. I wonder what year the domain will finally lapse and get picked up by a porn site.".to_owned(),
img: "http://imgs.xkcd.com/comics/theft_quadrants.png".to_owned().parse::<Url>().unwrap(),
title: "Theft Quadrants".to_owned(),
day: 24,
});
}
}