Fixed UI specification code.

[?]
Jun 25, 2021, 1:09 AM
4QOTH75I2VINLY52J75OR3E3B5CN5ITHJGOAKQYXI6PH3XLJ6DBQC

Dependencies

  • [2] 2SABVMY3 Finished into_json() functionality.
  • [3] 77SIQZ3E Separating out spec generation.
  • [4] LVMGQJGH Finished framework for checking series specifications with data.
  • [5] U4VCAFXQ Added data_type to TSSpec key.
  • [6] GQVS55HI Finished generate_ts_spec() function.
  • [*] 4MG5JFXT First record.

Change contents

  • replacement in src/serve_ui.rs at line 4
    [3.132][3.132:163]()
    use std::collections::HashMap;
    [3.132]
    [3.163]
    use std::str::FromStr;
  • edit in src/serve_ui.rs at line 6
    [3.164][3.164:189]()
    use serde::{Serialize};
  • edit in src/serve_ui.rs at line 9
    [3.244][3.244:270]()
    Error,
    ErrorKind,
  • edit in src/serve_ui.rs at line 11
    [3.292][3.292:307]()
    DateRange,
  • edit in src/serve_ui.rs at line 12
    [3.324][3.324:347]()
    RegularTimeSeries,
  • edit in src/serve_ui.rs at line 16
    [3.378][3.378:426]()
    };
    use crate::check_data::{
    SeriesMetaData,
  • replacement in src/serve_ui.rs at line 17
    [3.429][3.429:471]()
    use crate::serve_ts::{
    data_from_csv,
    [3.429]
    [3.471]
    use crate::error:: {
    Error,
    ErrorKind,
  • replacement in src/serve_ui.rs at line 37
    [3.818][3.818:879]()
    pub struct UISpec(pub HashMap<Country, Vec<UIGraphicSpec>>);
    [3.818]
    [3.879]
    pub struct UISpec(Vec<UIGraphicSpec>);
  • replacement in src/serve_ui.rs at line 40
    [3.926][3.926:1070]()
    type Error = Error;
    fn try_into(self) -> Result<UISpec, Error> {
    let countries: Vec<CountrySpec> = self.vec("ui::country")?;
    [3.926]
    [3.1070]
    type Error = keytree::Error;
  • replacement in src/serve_ui.rs at line 42
    [3.1071][3.1071:1227]()
    let mut h = HashMap::new();
    for country in countries {
    h.insert(country.key, country.value.0);
    }
    Ok(UISpec(h))
    [3.1071]
    [3.1227]
    fn try_into(self) -> Result<UISpec, Self::Error> {
    Ok(
    UISpec(self.vec("ui_spec::ui_graphic")?)
    )
  • replacement in src/serve_ui.rs at line 49
    [3.1236][3.1236:1301]()
    pub struct CountrySpec {
    key: Country,
    value: ValueSpec,
    [3.1236]
    [3.1301]
    /// ```
    /// ui_graphic:
    /// country: Australia
    /// index: 0
    ///
    /// time_series:
    /// data_type: u
    /// series: AUSURAMS_a
    /// transform: ident
    /// time_series:
    /// data_type: i
    /// series: _
    /// transform: ident
    /// line:
    /// x: 0
    /// y: 1
    /// ```
    pub struct UIGraphicSpec {
    ///
    pub country: Country,
    ///
    pub title: String,
    ///
    pub index: usize,
    ///
    pub time_series: Vec<UITimeSeriesSpec>,
    ///
    pub line: Vec<UILineSpec>,
  • replacement in src/serve_ui.rs at line 79
    [3.1304][3.1304:1379]()
    impl<'a> TryInto<CountrySpec> for KeyTreeRef<'a> {
    type Error = Error;
    [3.1304]
    [3.1379]
    impl<'a> TryInto<UIGraphicSpec> for KeyTreeRef<'a> {
    type Error = keytree::Error;
  • replacement in src/serve_ui.rs at line 82
    [3.1380][3.1380:1434]()
    fn try_into(self) -> Result<CountrySpec, Error> {
    [3.1380]
    [3.1434]
    fn try_into(self) -> Result<UIGraphicSpec, Self::Error> {
  • replacement in src/serve_ui.rs at line 84
    [3.1435][3.1435:1496]()
    let country_str: String = self.at("country::key")?;
    [3.1435]
    [3.1496]
    let country_str: String = self.at("ui_graphic::country")?;
  • replacement in src/serve_ui.rs at line 88
    [3.1573][3.1573:1680]()
    CountrySpec {
    key: country,
    value: self.at("country::value")?,
    [3.1573]
    [3.1680]
    UIGraphicSpec {
    country,
    index: self.at("ui_graphic::index")?,
    title: self.at("ui_graphic::title")?,
    time_series: self.vec("ui_graphic::time_series")?,
    line: self.vec("ui_graphic::line")?,
  • edit in src/serve_ui.rs at line 99
    [3.1713][3.1713:1755]()
    pub struct ValueSpec(Vec<UIGraphicSpec>);
  • edit in src/serve_ui.rs at line 100
    [3.1756][3.1756:1942]()
    impl<'a> TryInto<ValueSpec> for KeyTreeRef<'a> {
    type Error = Error;
    fn try_into(self) -> Result<ValueSpec, Error> {
    Ok(ValueSpec(self.vec("value::graphic")?))
    }
    }
  • replacement in src/serve_ui.rs at line 102
    [3.2013][3.2013:2618]()
    /// ui:
    /// country:
    /// key: Australia
    /// value:
    /// graphic:
    /// title: Unemployment and Inflation for Australia
    /// time_series:
    /// data_type: u
    /// series: AUSURAMS_a
    /// transform: ident
    /// time_series:
    /// data_type: i
    /// series: _
    /// transform: ident
    /// line:
    /// x: 0
    /// y: 1
    [3.2013]
    [3.2618]
    /// line:
    /// x: 0
    /// y: 1
  • replacement in src/serve_ui.rs at line 116
    [3.2929][3.2929:2953]()
    type Error = Error;
    [3.2929]
    [3.2953]
    type Error = keytree::Error;
  • replacement in src/serve_ui.rs at line 118
    [3.2954][3.2954:3007]()
    fn try_into(self) -> Result<UILineSpec, Error> {
    [3.2954]
    [3.3007]
    fn try_into(self) -> Result<UILineSpec, Self::Error> {
  • replacement in src/serve_ui.rs at line 122
    [3.3135][3.3135:3187]()
    Some(date) => Some(parse_date(&date)?),
    [3.3135]
    [3.3187]
    Some(date) => {
    Some(
    parse_date(&date)
    .map_err(|_|
    keytree::Error::new(keytree::ErrorKind::User(Error::new(ErrorKind::ParseDate(date)).to_string())))?
    )
    },
  • replacement in src/serve_ui.rs at line 150
    [3.3678][3.3678:4131]()
    fn parse_date(s: &str) -> Result<MonthlyDate, Error> {
    let year = s[..=4].parse::<usize>().map_err(|err| keytree::Error(Box::new(ErrorKind::User(err.to_string()))))?;
    let month = s[5..].parse::<usize>().map_err(|err| keytree::Error(Box::new(ErrorKind::User(err.to_string()))))?;
    Ok(MonthlyDate::ym(year, month))
    }
    #[test]
    fn test_parse_date() {
    let s = "1999-03";
    assert!(
    parse_date(s),
    MonthlyDate(1999, 3),
    )
    [3.3678]
    [3.4131]
    /// `Transform`s may include joining data, interpolation etc.
    pub enum Transform {
    /// No-op
    Ident,
  • replacement in src/serve_ui.rs at line 156
    [3.4134][3.4134:4223]()
    // Structs UIJson, UIGraphJson and UILineJson encapsulate data to be converted to JSON.
    [3.4134]
    [3.4223]
    impl FromStr for Transform {
    type Err = Error;
  • replacement in src/serve_ui.rs at line 159
    [3.4224][3.4224:4843]()
    /// `UIJson` are a collection of `LineJson` convertible to JSON for a ui graphic.
    #[derive(Serialize)]
    pub struct UIJson {
    country: Country,
    graphics: Vec<UIGraphicJson>,
    }
    impl UIJson {
    /// Build a new `UIJson` from a `UISpec` specification.
    pub fn new(ui_spec: &UISpec, country: Country) -> Self {
    let ui_country_spec = ui_spec.0.get(&country).unwrap();
    let mut builder = UIJson {
    country: country,
    graphics: Vec::new(),
    };
    for graphic_spec in ui_country_spec {
    builder.graphics.push(UIGraphicJson::new(graphic_spec, country));
    [3.4224]
    [3.4843]
    fn from_str(s: &str) -> Result<Self, Self::Err> {
    match s {
    "ident" => Ok(Transform::Ident),
    _ => Err(Error::new(ErrorKind::ParseTransform(s.into()))),
  • edit in src/serve_ui.rs at line 164
    [3.4853][3.4853:4870]()
    builder
  • edit in src/serve_ui.rs at line 165
    [3.4876][3.4876:5034]()
    }
    /// `UIGraphicJson` is a JSON representation of a UI graph.
    #[derive(Serialize)]
    pub struct UIGraphicJson {
    title: String,
    lines: Vec<UILineJson>,
  • edit in src/serve_ui.rs at line 166
    [3.5036][3.5036:5392]()
    impl UIGraphicJson {
    pub fn new(graphic_spec: &UIGraphicSpec, country: Country) -> Self {
    let mut builder = UIGraphicJson {
    title: graphic_spec.title.clone(),
    lines: Vec::new(),
    };
    for line_spec in &graphic_spec.line {
    builder.lines.push(UILineJson::new(&line_spec, country));
    };
  • replacement in src/serve_ui.rs at line 167
    [3.5393][3.5393:5415]()
    builder
    }
    [3.5393]
    [3.5415]
    /// ```
    /// time_series:
    /// data_type: u
    /// series: AUSURAMS_a
    /// transform: ident
    /// ```
    pub struct UITimeSeriesSpec {
    start_date: Option<MonthlyDate>,
    end_date: Option<MonthlyDate>,
    data_type: DataType,
    series: String,
    transform: Transform,
  • edit in src/serve_ui.rs at line 180
    [3.5417][3.5417:5558]()
    /// `UILineJson` are two time-series
    #[derive(Serialize)]
    pub struct UILineJson {
    x: RegularTimeSeries<1>,
    y: RegularTimeSeries<1>,
  • replacement in src/serve_ui.rs at line 181
    [3.5559][3.5559:5617]()
    x_meta: SeriesMetaData,
    y_meta: SeriesMetaData,
    }
    [3.5559]
    [3.5617]
    /// ```
    /// time_series:
    /// data_type: u
    /// series: AUSURAMS_a
    /// transform: ident
    /// ```
    impl<'a> TryInto<UITimeSeriesSpec> for KeyTreeRef<'a> {
    type Error = keytree::Error;
  • replacement in src/serve_ui.rs at line 190
    [3.5618][3.5618:5771]()
    impl UILineJson {
    /// Build a new `UILineJson` from a `UILineSpec` specification.
    pub fn new(line_spec: &UILineSpec, country: Country) -> Self {
    [3.5618]
    [3.5771]
    fn try_into(self) -> Result<UITimeSeriesSpec, Self::Error> {
  • replacement in src/serve_ui.rs at line 192
    [3.5780][3.5780:6016]()
    let (mut x_data, x_meta) = data_from_csv(&line_spec.x, country, DataType::U);
    let range = DateRange::new(
    line_spec.start_date,
    line_spec.end_date,
    );
    x_data.with_range(&range);
    [3.5780]
    [3.6016]
    let data_type_str: String = self.at("time_series::data_type")?;
    let data_type = DataType::from_str(&data_type_str).unwrap();
  • replacement in src/serve_ui.rs at line 195
    [3.6017][3.6017:6283]()
    let (mut y_data, y_meta) = data_from_csv(&line_spec.y, country, DataType::Inf);
    y_data.with_range(&range);
    UILineJson {
    x: x_data,
    y: y_data,
    x_meta: x_meta,
    y_meta: y_meta,
    }
    }
    }
    [3.6017]
    [3.6283]
    let transform_str: String = self.at("time_series::transform")?;
    let transform = Transform::from_str(&transform_str).unwrap();
  • replacement in src/serve_ui.rs at line 198
    [3.6284][3.6284:6788]()
    /// ```
    /// ui:
    /// country:
    /// key: Australia
    /// value:
    /// graphic:
    /// title: Unemployment and Inflation for Australia
    /// line:
    /// x: AUSURAMS_a
    /// y: _
    /// start_date: _
    /// end_date: _
    /// line:
    /// ```
    pub struct UIGraphicSpec {
    pub title: String,
    pub line: Vec<UILineSpec>,
    }
    [3.6284]
    [3.6788]
    let start_date_str: Option<String> = self.op("time_series::start_date")?;
    let start_date = match start_date_str {
    Some(date) => Some(parse_date(&date)?),
    None => None,
    };
  • replacement in src/serve_ui.rs at line 204
    [3.6789][3.6789:6866]()
    impl<'a> TryInto<UIGraphicSpec> for KeyTreeRef<'a> {
    type Error = Error;
    [3.6789]
    [3.6866]
    let end_date_str: Option<String> = self.op("time_series::end_date")?;
    let end_date = match end_date_str {
    Some(date) => Some(parse_date(&date)?),
    None => None,
    };
  • edit in src/serve_ui.rs at line 210
    [3.6867][3.6867:6923]()
    fn try_into(self) -> Result<UIGraphicSpec, Error> {
  • replacement in src/serve_ui.rs at line 211
    [3.6935][3.6935:7070]()
    UIGraphicSpec {
    title: self.at("ui_graphic::title")?,
    line: self.vec("ui_graphic::line")?,
    [3.6935]
    [3.7070]
    UITimeSeriesSpec {
    data_type,
    start_date,
    end_date,
    series: self.at("time_series::series")?,
    transform,
  • edit in src/serve_ui.rs at line 222
    [3.7103]
    [3.7103]
    fn parse_date(s: &str) -> Result<MonthlyDate, keytree::Error> {
    let year = s[..=4].parse::<usize>().map_err(|err| keytree::Error(Box::new(keytree::ErrorKind::User(err.to_string()))))?;
    let month = s[5..].parse::<usize>().map_err(|err| keytree::Error(Box::new(keytree::ErrorKind::User(err.to_string()))))?;
    Ok(MonthlyDate::ym(year, month))
    }
  • edit in src/serve_ui.rs at line 228
    [3.7104]
    #[test]
    fn test_parse_date() {
    let s = "1999-03";
    assert!(
    parse_date(s),
    MonthlyDate(1999, 3),
    )
    }
  • replacement in src/serve_ts.rs at line 218
    [3.2648][3.2648:2678]()
    country: country,
    [3.2648]
    [3.2678]
    country,
  • replacement in src/lib.rs at line 154
    [2.7836][3.13247:13268](),[3.13247][3.13247:13268]()
    // pub mod serve_ui;
    [2.7836]
    [3.10717]
    pub mod serve_ui;