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,
});
}
}