covid19 0.3.0

Wrapper for cv19api https://lbandc.github.io/2020/04/14/project-cv19api.html
Documentation
use chrono::NaiveDate;
use std::collections::HashMap;

pub type Places = Vec<PlaceData>;
pub type Regions = Vec<RegionData>;
pub type Countries = Vec<CountryData>;

#[derive(Debug, Serialize, Deserialize)]
pub struct CountryData {
    pub country: Country,
    pub dates: HashMap<NaiveDate, DataPoint>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct RegionData {
    pub region: Region,
    pub dates: HashMap<NaiveDate, DataPoint>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct PlaceData {
    pub place: Place,
    pub dates: HashMap<NaiveDate, DataPoint>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Place {
    pub key: String,
    pub name: String,
    pub full_name: String,
    pub country: Country,
    pub region: Region,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Country {
    pub location_type: Option<String>,
    pub key: String,
    pub name: String,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Region {
    pub location_type: Option<String>,
    pub key: String,
    pub name: String,
    pub full_name: String,
    pub country: Country,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct DataPoint {
    pub new: Stats,
    pub cumulative: Stats,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Stats {
    pub cases: u32,
    pub deaths: u32,
    pub recoveries: u32,
}

#[cfg(test)]
mod tests {
    use super::{Countries, DataPoint, Place, Places, Regions};
    use chrono::NaiveDate;

    #[test]
    fn test_countries_stats() {
        let json = r#"
        [
            {
                "country": {
                    "key": "united-states",
                    "name": "United States"
                },
                "dates": {
                    "2020-01-22": {
                        "new": {
                            "cases": 1,
                            "deaths": 0,
                            "recoveries": 0
                        },
                        "cumulative": {
                            "cases": 1,
                            "deaths": 0,
                            "recoveries": 0
                        }
                    },
                    "2020-01-23": {
                        "new": {
                            "cases": 0,
                            "deaths": 0,
                            "recoveries": 0
                        },
                        "cumulative": {
                            "cases": 1,
                            "deaths": 0,
                            "recoveries": 0
                        }
                    }
                }
            }
        ]
        "#;

        let c: Result<Countries, serde_json::Error> = serde_json::from_str(json);
        assert!(c.is_ok());
    }

    #[test]
    fn test_region_stats() {
        let json = r#"[
            {
                "region": {
                    "key": "new-york-united-states",
                    "name": "New York",
                    "full_name": "New York, United States",
                    "country": {
                        "location_type": "country",
                        "key": "united-states",
                        "name": "United States"
                    }
                },
                "dates": {
                    "2020-03-01": {
                        "new": {
                            "cases": 1,
                            "deaths": 0,
                            "recoveries": 0
                        },
                        "cumulative": {
                            "cases": 1,
                            "deaths": 0,
                            "recoveries": 0
                        }
                    },
                    "2020-03-02": {
                        "new": {
                            "cases": 0,
                            "deaths": 0,
                            "recoveries": 0
                        },
                        "cumulative": {
                            "cases": 1,
                            "deaths": 0,
                            "recoveries": 0
                        }
                    }
                }
            }
        ]"#;

        let r: Result<Regions, serde_json::Error> = serde_json::from_str(json);
        assert!(r.is_ok())
    }
    #[test]
    fn test_places() {
        let json = r#"
        [{
            "place": {
                "key": "new-york-city-new-york-united-states",
                "name": "New York City",
                "full_name": "New York City, New York, United States",
                "country": {
                    "location_type": "country",
                    "key": "united-states",
                    "name": "United States"
                },
                "region": {
                    "location_type": "region",
                    "key": "new-york-united-states",
                    "name": "New York",
                    "full_name": "New York, United States",
                    "country": {
                        "location_type": "country",
                        "key": "united-states",
                        "name": "United States"
                    }
                }
            },
            "dates": {
                "2020-03-01": {
                    "new": {
                        "cases": 1,
                        "deaths": 0,
                        "recoveries": 0
                    },
                    "cumulative": {
                        "cases": 1,
                        "deaths": 0,
                        "recoveries": 0
                    }
                },
                "2020-03-02": {
                    "new": {
                        "cases": 0,
                        "deaths": 0,
                        "recoveries": 0
                    },
                    "cumulative": {
                        "cases": 1,
                        "deaths": 0,
                        "recoveries": 0
                    }
                }
            }
        }]"#;
        let places: Places = serde_json::from_str(json).unwrap();
        let first_place = places.first().unwrap();
        let dt = first_place
            .dates
            .get(&NaiveDate::from_ymd(2020, 3, 2))
            .unwrap();
        assert_eq!(dt.new.deaths, 0)
    }

    #[test]
    fn deserialize_date() {
        let sample_date = r#"
        {
            "new": {
                "cases": 1,
                "deaths": 37,
                "recoveries": 10
            },
            "cumulative": {
                "cases": 30,
                "deaths":65,
                "recoveries": 0
            }
        }
        "#;

        let d: DataPoint = serde_json::from_str(sample_date).unwrap();
        assert_eq!(d.new.cases, 1);
        assert_eq!(d.new.deaths, 37);
        assert_eq!(d.new.recoveries, 10);
        assert_eq!(d.cumulative.cases, 30);
        assert_eq!(d.cumulative.deaths, 65);
        assert_eq!(d.cumulative.recoveries, 0);
    }

    #[test]
    fn deserialize_place() {
        let sample_data = r#"
            {
                "key": "new-york-city-new-york-united-states",
                "name": "New York City",
                "full_name": "New York City, New York, United States",
                "country": {
                    "location_type": "country",
                    "key": "united-states",
                    "name": "United States"
                },
                "region": {
                    "location_type": "region",
                    "key": "new-york-united-states",
                    "name": "New York",
                    "full_name": "New York, United States",
                    "country": {
                        "location_type": "country",
                        "key": "united-states",
                        "name": "United States"
                    }
                }
            }
        "#;

        let place: Place = serde_json::from_str(sample_data).unwrap();

        assert_eq!(place.key, "new-york-city-new-york-united-states");
        assert_eq!(place.region.country.key, "united-states");
        assert_eq!(place.country.location_type, Some("country".to_string()));
    }
}