Fixed UI specification code.
[?]
Jun 25, 2021, 1:09 AM
4QOTH75I2VINLY52J75OR3E3B5CN5ITHJGOAKQYXI6PH3XLJ6DBQCDependencies
- [2]
2SABVMY3Finished into_json() functionality. - [3]
77SIQZ3ESeparating out spec generation. - [4]
LVMGQJGHFinished framework for checking series specifications with data. - [5]
U4VCAFXQAdded data_type to TSSpec key. - [6]
GQVS55HIFinished generate_ts_spec() function. - [*]
4MG5JFXTFirst record.
Change contents
- replacement in src/serve_ui.rs at line 4
use std::collections::HashMap;use std::str::FromStr; - edit in src/serve_ui.rs at line 6
use serde::{Serialize}; - edit in src/serve_ui.rs at line 9
Error,ErrorKind, - edit in src/serve_ui.rs at line 11
DateRange, - edit in src/serve_ui.rs at line 12
RegularTimeSeries, - edit in src/serve_ui.rs at line 16
};use crate::check_data::{SeriesMetaData, - replacement in src/serve_ui.rs at line 17
use crate::serve_ts::{data_from_csv,use crate::error:: {Error,ErrorKind, - replacement in src/serve_ui.rs at line 37
pub struct UISpec(pub HashMap<Country, Vec<UIGraphicSpec>>);pub struct UISpec(Vec<UIGraphicSpec>); - replacement in src/serve_ui.rs at line 40
type Error = Error;fn try_into(self) -> Result<UISpec, Error> {let countries: Vec<CountrySpec> = self.vec("ui::country")?;type Error = keytree::Error; - replacement in src/serve_ui.rs at line 42
let mut h = HashMap::new();for country in countries {h.insert(country.key, country.value.0);}Ok(UISpec(h))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
pub struct CountrySpec {key: Country,value: ValueSpec,/// ```/// 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
impl<'a> TryInto<CountrySpec> for KeyTreeRef<'a> {type Error = Error;impl<'a> TryInto<UIGraphicSpec> for KeyTreeRef<'a> {type Error = keytree::Error; - replacement in src/serve_ui.rs at line 82
fn try_into(self) -> Result<CountrySpec, Error> {fn try_into(self) -> Result<UIGraphicSpec, Self::Error> { - replacement in src/serve_ui.rs at line 84
let country_str: String = self.at("country::key")?;let country_str: String = self.at("ui_graphic::country")?; - replacement in src/serve_ui.rs at line 88
CountrySpec {key: country,value: self.at("country::value")?,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
pub struct ValueSpec(Vec<UIGraphicSpec>); - edit in src/serve_ui.rs at line 100
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
/// 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/// line:/// x: 0/// y: 1 - replacement in src/serve_ui.rs at line 116
type Error = Error;type Error = keytree::Error; - replacement in src/serve_ui.rs at line 118
fn try_into(self) -> Result<UILineSpec, Error> {fn try_into(self) -> Result<UILineSpec, Self::Error> { - replacement in src/serve_ui.rs at line 122
Some(date) => Some(parse_date(&date)?),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
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),)/// `Transform`s may include joining data, interpolation etc.pub enum Transform {/// No-opIdent, - replacement in src/serve_ui.rs at line 156
// Structs UIJson, UIGraphJson and UILineJson encapsulate data to be converted to JSON.impl FromStr for Transform {type Err = Error; - replacement in src/serve_ui.rs at line 159
/// `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));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
builder - edit in src/serve_ui.rs at line 165
}/// `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
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
builder}/// ```/// 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
/// `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
x_meta: SeriesMetaData,y_meta: SeriesMetaData,}/// ```/// 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
impl UILineJson {/// Build a new `UILineJson` from a `UILineSpec` specification.pub fn new(line_spec: &UILineSpec, country: Country) -> Self {fn try_into(self) -> Result<UITimeSeriesSpec, Self::Error> { - replacement in src/serve_ui.rs at line 192
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);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
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,}}}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
/// ```/// 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>,}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
impl<'a> TryInto<UIGraphicSpec> for KeyTreeRef<'a> {type Error = Error;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
fn try_into(self) -> Result<UIGraphicSpec, Error> { - replacement in src/serve_ui.rs at line 211
UIGraphicSpec {title: self.at("ui_graphic::title")?,line: self.vec("ui_graphic::line")?,UITimeSeriesSpec {data_type,start_date,end_date,series: self.at("time_series::series")?,transform, - edit in src/serve_ui.rs at line 222
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
country: country,country, - replacement in src/lib.rs at line 154
// pub mod serve_ui;pub mod serve_ui;