Take advantage of keytree FromStr functionality.

[?]
Jul 3, 2021, 1:39 AM
XI5ALEH6NPTQWB6O62QV62EP4H3K7WSNTHCOGT3LZIIU6I2YDGIQC

Dependencies

  • [2] 4QOTH75I Fixed UI specification code.
  • [3] IKPVWWLK Filter unemployment rate series.
  • [4] CUADTSHQ Save csv data as multiple files.
  • [5] UCSU3QE4 Created keytree generator for u and cpi.
  • [6] AIFRDCG2 Split off countries mod into a separate crate.
  • [7] 2SABVMY3 Finished into_json() functionality.
  • [8] LVMGQJGH Finished framework for checking series specifications with data.
  • [9] 77SIQZ3E Separating out spec generation.
  • [10] 5POF332L Working on fn cpi_included().
  • [11] U4VCAFXQ Added data_type to TSSpec key.
  • [12] GQVS55HI Finished generate_ts_spec() function.
  • [*] 4MG5JFXT First record.
  • [*] GUXZCEWW Added Country enum.

Change contents

  • edit in src/serve_ui.rs at line 9
    [3.270][3.270:292](),[3.307][3.307:324]()
    };
    use time_series::{
    MonthlyDate,
  • edit in src/serve_ui.rs at line 13
    [3.378]
    [3.426]
    MonthlyDate,
    SeriesId,
  • replacement in src/serve_ui.rs at line 17
    [2.25][2.25:72](),[2.72][3.471:474](),[3.471][3.471:474]()
    use crate::error:: {
    Error,
    ErrorKind,
    };
    [2.25]
    [3.474]
    use crate::error::*;
    // --- JSON Serializers -------------------------------------------------------------
    // pub struct UIJson(HashMap<(Country Index),Vec<Graphic>
    // Do we want meta for each line?
    // --- Specification ----------------------------------------------------------------
  • replacement in src/serve_ui.rs at line 49
    [2.214][2.214:267]()
    UISpec(self.vec("ui_spec::ui_graphic")?)
    [2.214]
    [2.267]
    UISpec(self.vec_at("ui_spec::ui_graphic")?)
  • edit in src/serve_ui.rs at line 88
    [2.1057][3.1434:1435](),[3.1434][3.1434:1435](),[3.1435][2.1058:1125](),[2.1125][3.1496:1560](),[3.1496][3.1496:1560]()
    let country_str: String = self.at("ui_graphic::country")?;
    let country = Country::from_str(&country_str).unwrap();
  • replacement in src/serve_ui.rs at line 91
    [2.1154][2.1154:1438]()
    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")?,
    [2.1154]
    [3.1680]
    country: self.value("ui_graphic::country")?,
    index: self.value("ui_graphic::index")?,
    title: self.value("ui_graphic::title")?,
    time_series: self.vec_at("ui_graphic::time_series")?,
    line: self.vec_at("ui_graphic::line")?,
  • replacement in src/serve_ui.rs at line 111
    [3.2774][3.2774:2804]()
    x: String,
    y: String,
    [3.2774]
    [3.2804]
    x: SeriesId,
    y: SeriesId,
  • edit in src/serve_ui.rs at line 121
    [2.1587][3.3007:3135](),[3.3007][3.3007:3135](),[3.3135][2.1588:1846](),[2.1846][3.3187:3444](),[3.3187][3.3187:3444]()
    let start_date_str: Option<String> = self.op("line::start_date")?;
    let start_date_opt = match start_date_str {
    Some(date) => {
    Some(
    parse_date(&date)
    .map_err(|_|
    keytree::Error::new(keytree::ErrorKind::User(Error::new(ErrorKind::ParseDate(date)).to_string())))?
    )
    },
    None => None,
    };
    let end_date_str: Option<String> = self.op("line::end_date")?;
    let end_date_opt = match end_date_str {
    Some(date) => Some(parse_date(&date)?),
    None => None,
    };
  • replacement in src/serve_ui.rs at line 123
    [3.3481][3.3481:3645]()
    x: self.at("line::x")?,
    y: self.at("line::y")?,
    start_date: start_date_opt,
    end_date: end_date_opt,
    [3.3481]
    [3.3645]
    x: self.value("line::x")?,
    y: self.value("line::y")?,
    start_date: self.opt_value("line::start_date")?,
    end_date: self.opt_value("line::end_date")?,
  • replacement in src/serve_ui.rs at line 144
    [2.2125][2.2125:2197]()
    _ => Err(Error::new(ErrorKind::ParseTransform(s.into()))),
    [2.2125]
    [3.4843]
    _ => Err(parse_transform(s)),
  • edit in src/serve_ui.rs at line 173
    [2.2759][3.5771:5780](),[3.5771][3.5771:5780](),[3.5780][2.2760:2901](),[2.2901][3.6016:6017](),[3.6016][3.6016:6017](),[3.6017][2.2902:3044](),[2.3044][3.6283:6284](),[3.6283][3.6283:6284](),[3.6284][2.3045:3264](),[2.3264][3.6788:6789](),[3.6788][3.6788:6789](),[3.6789][2.3265:3476](),[2.3476][3.6866:6867](),[3.6866][3.6866:6867]()
    let data_type_str: String = self.at("time_series::data_type")?;
    let data_type = DataType::from_str(&data_type_str).unwrap();
    let transform_str: String = self.at("time_series::transform")?;
    let transform = Transform::from_str(&transform_str).unwrap();
    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,
    };
    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,
    };
  • replacement in src/serve_ui.rs at line 175
    [2.3508][2.3508:3673]()
    data_type,
    start_date,
    end_date,
    series: self.at("time_series::series")?,
    transform,
    [2.3508]
    [3.7070]
    data_type: self.value("time_series::data_type")?,
    start_date: self.opt_value("time_series::start_date")?,
    end_date: self.opt_value("time_series::end_date")?,
    series: self.value("time_series::series")?,
    transform: self.value("time_series::transform")?,
  • replacement in src/serve_ui.rs at line 185
    [3.7103][2.3674:4027]()
    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))
    }
    [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))
    // }
  • replacement in src/serve_ui.rs at line 191
    [3.7104][2.4028:4156]()
    #[test]
    fn test_parse_date() {
    let s = "1999-03";
    assert!(
    parse_date(s),
    MonthlyDate(1999, 3),
    )
    }
    [3.7104]
    [2.4156]
    // #[test]
    // fn test_parse_date() {
    // let s = "1999-03";
    // assert!(
    // parse_date(s),
    // MonthlyDate(1999, 3),
    // )
    // }
  • edit in src/serve_ts.rs at line 3
    [3.20][3.20:30]()
    Into,
  • replacement in src/serve_ts.rs at line 144
    [3.2241][3.1228:1296](),[3.1228][3.1228:1296]()
    let page_vec: Vec<TSPageSpec> = self.vec("ts_spec::page")?;
    [3.2241]
    [3.1296]
    let page_vec: Vec<TSPageSpec> = self.vec_at("ts_spec::page")?;
  • edit in src/serve_ts.rs at line 209
    [3.2419][3.9603:9604](),[3.2680][3.9603:9604](),[3.9603][3.9603:9604](),[3.9604][3.2420:2484](),[3.2484][3.9665:9729](),[3.9665][3.9665:9729](),[3.9729][3.2485:2623](),[3.2623][3.9729:9734](),[3.9729][3.9729:9734]()
    let country_str: String = self.at("country::country")?;
    let country = Country::from_str(&country_str).unwrap();
    let data_type_str: String = self.at("country::data_type")?;
    let data_type = DataType::from_str(&data_type_str).unwrap();
  • replacement in src/serve_ts.rs at line 210
    [3.2648][2.4158:4179](),[2.4179][3.2678:2712](),[3.2678][3.2678:2712](),[3.2712][3.9788:9841](),[3.9788][3.9788:9841]()
    country,
    data_type: data_type,
    graphics: self.vec("country::graphic")?,
    [3.2648]
    [3.9841]
    country: self.value("country::country")?,
    data_type: self.value("country::data_type")?,
    graphics: self.vec_at("country::graphic")?,
  • replacement in src/serve_ts.rs at line 289
    [3.10902][3.10902:11011]()
    height: self.op("graphic::height")?,
    series_ids: self.vec("graphic::data")?,
    [3.10902]
    [3.11011]
    height: self.opt_value("graphic::height")?,
    series_ids: self.vec_value("graphic::data")?,
  • edit in src/serve_ts.rs at line 357
    [3.4607][3.4607:4710](),[3.4710][3.12081:12227](),[3.12081][3.12081:12227](),[3.12227][3.4711:4810](),[3.4810][3.12287:12353](),[3.12287][3.12287:12353]()
    let data_type_str: String = self.at("key::data_type")
    .map_err(|err| err.into())?;
    // All KeyTree strings are internal, so if this fails it is a bug.
    let data_type = DataType::from_str(&data_type_str).unwrap();
    let country_str: String = self.at("key::country")
    .map_err(|err| err.into())?;
    let country = Country::from_str(&country_str).unwrap();
  • replacement in src/serve_ts.rs at line 358
    [3.12374][3.12374:12438]()
    data_type: data_type,
    country: country,
    [3.12374]
    [3.12438]
    data_type: self.value("key::data_type")?,
    country: self.value("key::country")?,
  • edit in src/lib.rs at line 157
    [3.10732]
    [3.10757]
    use std::str::FromStr;
  • edit in src/lib.rs at line 162
    [15.498]
    [3.1794]
    use crate::error::Error;
    use crate::error::*;
    /// A date that can be parsed from a string like "07-08-2010".
    pub struct MonthlyDate(time_series::MonthlyDate);
    impl FromStr for MonthlyDate {
    type Err = Error;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
    let year = s[..4].parse().map_err(|_| parse_date("failed"))?;
    let month = s[5..7].parse().map_err(|_| parse_date("failed"))?;
    Ok(MonthlyDate(time_series::MonthlyDate::ym(year, month)))
    }
    }
    /// Represents a FRED series id.
    pub struct SeriesId(String);
    impl FromStr for SeriesId {
    type Err = ();
    fn from_str(s: &str) -> Result<Self, ()> {
    Ok(SeriesId(String::from(s)))
    }
    }
  • replacement in src/lib.rs at line 203
    [3.3393][3.11060:11076]()
    impl DataType {
    [3.3393]
    [3.7900]
    impl FromStr for DataType {
    type Err = Error;
  • replacement in src/lib.rs at line 208
    [3.7971][3.11076:11123](),[3.11076][3.11076:11123]()
    pub fn from_str(s: &str) -> Option<Self> {
    [3.7971]
    [3.11123]
    fn from_str(s: &str) -> Result<Self, Self::Err> {
  • replacement in src/lib.rs at line 210
    [3.11141][3.11141:11330]()
    "u" => Some(DataType::U),
    "cpi" => Some(DataType::Cpi),
    "inf" => Some(DataType::Inf),
    "int" => Some(DataType::Int),
    _ => None,
    [3.11141]
    [3.15738]
    "u" => Ok(DataType::U),
    "cpi" => Ok(DataType::Cpi),
    "inf" => Ok(DataType::Inf),
    "int" => Ok(DataType::Int),
    _ => Err(parse_datatype(s)),
  • edit in src/check_data.rs at line 4
    [3.13268]
    [3.13325]
    use std::str::FromStr;
  • edit in src/check_data.rs at line 26
    [3.8100][3.8100:8149]()
    };
    use crate::error::{
    Error,
    ErrorKind,
  • edit in src/check_data.rs at line 27
    [3.8152]
    [3.13411]
    use crate::error::*;
  • replacement in src/check_data.rs at line 97
    [3.9099][3.9099:9233]()
    return Err(Error::new(
    ErrorKind::SpecErrorStatus(series_id, checked_series.error.clone())
    ))
    [3.9099]
    [3.9233]
    return Err(
    spec_has_error_status(&series_id, &checked_series.error.clone())
    )
  • replacement in src/check_data.rs at line 112
    [3.9505][3.9505:9637]()
    .map_err(|err| Error::new(
    ErrorKind::NotRegular(checked_series.id.clone())
    ))?
    [3.9505]
    [3.9637]
    .map_err(|_| time_series_not_regular(&checked_series.id.clone()))?
  • replacement in src/check_data.rs at line 239
    [3.15566][3.11015:11073]()
    CheckedDataSpec(self.vec("seriess::series")?)
    [3.15566]
    [3.15623]
    CheckedDataSpec(self.vec_at("seriess::series")?)
  • replacement in src/check_data.rs at line 272
    [3.11209][3.11209:11259]()
    pub time_stamp: Option<time::OffsetDateTime>,
    [3.11209]
    [3.15815]
    pub time_stamp: Option<TimeStamp>,
    }
    /// A timestamp.
    #[derive(Clone, Debug)]
    pub struct TimeStamp(time::OffsetDateTime);
    impl TimeStamp {
    fn format(self, format: &str) -> String {
    self.0.format(format)
    }
    fn now() -> Self {
    let inner = OffsetDateTime::now_utc();
    TimeStamp(inner)
    }
    }
    impl FromStr for TimeStamp {
    type Err = Error;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
    match OffsetDateTime::parse(s, "%Y %T") {
    Ok(stamp) => Ok(TimeStamp(stamp)),
    Err(_) => Err(parse_timestamp(s)),
    }
    }
  • replacement in src/check_data.rs at line 346
    [3.16806][3.11283:11346]()
    self.time_stamp = Some(OffsetDateTime::now_utc());
    [3.16806]
    [3.16868]
    self.time_stamp = Some(TimeStamp::now());
  • replacement in src/check_data.rs at line 404
    [3.18467][3.18467:18511]()
    Some(ts) => ts.format("%F %T"),
    [3.18467]
    [3.18511]
    Some(ts) => ts.clone().format("%F %T"),
  • edit in src/check_data.rs at line 416
    [3.16609][3.16609:16745]()
    let data_type_str: String = self.at("series::data_type")?;
    let data_type = DataType::from_str(&data_type_str).unwrap();
  • replacement in src/check_data.rs at line 417
    [3.16746][3.16746:16873](),[3.16873][3.18614:18686]()
    let country_str: String = self.at("series::country")?;
    let country = Country::from_str(&country_str).unwrap();
    let date_str: Option<String> = self.op("series::time_stamp")?;
    [3.16746]
    [3.18686]
    // let time_stamp = match date_str {
    // Some(date_str) => {
    // Some(OffsetDateTime::parse(date_str, "%Y %T").unwrap())
    // },
    // None => None,
    // };
  • edit in src/check_data.rs at line 424
    [3.18687][3.18687:18761](),[3.18761][3.11347:11419](),[3.11419][3.18836:18888](),[3.18836][3.18836:18888](),[3.18888][3.16873:16874](),[3.16873][3.16873:16874]()
    let time_stamp = match date_str {
    Some(date_str) => {
    Some(OffsetDateTime::parse(date_str, "%Y %T").unwrap())
    },
    None => None,
    };
  • replacement in src/check_data.rs at line 426
    [3.16919][3.16919:17066](),[3.17066][3.18889:18917]()
    data_type,
    country,
    id: self.at("series::id")?,
    error: self.at("series::error")?,
    time_stamp,
    [3.16919]
    [3.17066]
    data_type: self.value("series::data_type")?,
    country: self.value("series::country")?,
    id: self.value("series::id")?,
    error: self.value("series::error")?,
    time_stamp: self.opt_value("series::time_stamp")?,
  • replacement in src/check_data.rs at line 494
    [3.20052][3.20052:20596]()
    realtime: self.at("series_meta::realtime")?,
    id: self.at("series_meta::id")?,
    title: self.at("series_meta::title")?,
    observation_start: self.at("series_meta::observation_start")?,
    observation_end: self.at("series_meta::observation_end")?,
    frequency: self.at("series_meta::frequency")?,
    seasonal_adjustment: self.at("series_meta::seasonal_adjustment")?,
    [3.20052]
    [3.20596]
    realtime: self.value("series_meta::realtime")?,
    id: self.value("series_meta::id")?,
    title: self.value("series_meta::title")?,
    observation_start: self.value("series_meta::observation_start")?,
    observation_end: self.value("series_meta::observation_end")?,
    frequency: self.value("series_meta::frequency")?,
    seasonal_adjustment: self.value("series_meta::seasonal_adjustment")?,
  • replacement in src/build_spec.rs at line 1036
    [3.61674][3.61674:61724]()
    DataSpec(self.vec("seriess:series")?)
    [3.61674]
    [3.61724]
    DataSpec(self.vec_at("seriess:series")?)
  • edit in src/build_spec.rs at line 1080
    [3.62617][3.62617:62882]()
    let data_type_str: String = self.at("series::data_type")?;
    let data_type = DataType::from_str(&data_type_str).unwrap();
    let country_str: String = self.at("series::country")?;
    let country = Country::from_str(&country_str).unwrap();
  • replacement in src/build_spec.rs at line 1082
    [3.62920][3.62920:63017]()
    data_type,
    country,
    id: self.at("series::id")?,
    [3.62920]
    [3.63017]
    data_type: self.value("series::data_type")?,
    country: self.value("series::country")?,
    id: self.value("series::id")?,