Skip to content

Commit 4540d0e

Browse files
committed
Handle meta ver in encoding/decoding
1 parent 5f7d227 commit 4540d0e

4 files changed

Lines changed: 68 additions & 51 deletions

File tree

src/haystack/encoding/json/decode.rs

Lines changed: 56 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crate::haystack::val::{
1010

1111
use crate::haystack::timezone::make_date_time_with_tz;
1212
use crate::units::get_unit;
13-
use crate::val::GRID_FORMAT_VERSION;
13+
use crate::val::{GRID_FORMAT_VERSION, VER};
1414

1515
use chrono::{Offset, Utc};
1616
use serde::de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor};
@@ -470,53 +470,12 @@ fn parse_grid(dict: &Dict) -> Result<HVal, JsonErr> {
470470
match dict.get_list("rows") {
471471
Some(rows) => match dict.get_list("cols") {
472472
Some(cols) => {
473-
let mut grid_ver = GRID_FORMAT_VERSION.to_string();
474-
473+
let (meta, ver) = parse_grid_meta_and_ver(dict);
475474
let grid = Grid {
476-
meta: dict.get_dict("meta").cloned().map(|mut meta| {
477-
if let Some(ver) = meta.get_str("ver") {
478-
grid_ver = ver.value.to_owned();
479-
};
480-
meta.remove("ver");
481-
meta
482-
}),
483-
columns: {
484-
let cols: Result<Vec<Column>, JsonErr> = cols
485-
.iter()
486-
.map(|col| match col {
487-
HVal::Dict(dict) => match dict.get_str("name") {
488-
Some(name) => match dict.get("meta") {
489-
Some(meta) => match meta {
490-
HVal::Dict(meta) => Ok(Column {
491-
name: name.value.clone(),
492-
meta: Some(meta.clone()),
493-
}),
494-
_ => Err(JsonErr::custom("Invalid 'meta'")),
495-
},
496-
None => Ok(Column {
497-
name: name.value.clone(),
498-
meta: None,
499-
}),
500-
},
501-
None => Err(JsonErr::custom("Missing or invalid 'name'")),
502-
},
503-
_ => Err(JsonErr::custom("Invalid column type, expected a Dict")),
504-
})
505-
.collect();
506-
cols?
507-
},
508-
509-
rows: {
510-
let rows: Result<Vec<Dict>, JsonErr> = rows
511-
.iter()
512-
.map(|row| match row {
513-
HVal::Dict(row) => Ok(row.clone()),
514-
_ => Err(JsonErr::custom("Invalid row type, expected a Dict")),
515-
})
516-
.collect();
517-
rows?
518-
},
519-
ver: grid_ver,
475+
meta,
476+
columns: parse_grid_columns(cols)?,
477+
rows: parse_grid_rows(rows)?,
478+
ver,
520479
};
521480
Ok(grid.into())
522481
}
@@ -525,3 +484,53 @@ fn parse_grid(dict: &Dict) -> Result<HVal, JsonErr> {
525484
None => Err(JsonErr::custom("Missing or invalid 'rows'")),
526485
}
527486
}
487+
488+
fn parse_grid_meta_and_ver(dict: &Dict) -> (Option<Dict>, String) {
489+
let mut meta = dict.get_dict("meta").cloned();
490+
let mut grid_ver = GRID_FORMAT_VERSION.to_string();
491+
492+
if let Some(ref mut meta_dict) = meta {
493+
if let Some(ver) = meta_dict.get_str(VER) {
494+
grid_ver = ver.value.to_owned();
495+
meta_dict.remove(VER);
496+
}
497+
498+
// If the meta dict is empty then use none.
499+
if meta_dict.is_empty() {
500+
meta = None;
501+
}
502+
}
503+
504+
(meta, grid_ver)
505+
}
506+
507+
fn parse_grid_columns(cols: &List) -> Result<Vec<Column>, JsonErr> {
508+
cols.iter()
509+
.map(|col| match col {
510+
HVal::Dict(dict) => match dict.get_str("name") {
511+
Some(name) => match dict.get("meta") {
512+
Some(HVal::Dict(meta)) => Ok(Column {
513+
name: name.value.clone(),
514+
meta: Some(meta.clone()),
515+
}),
516+
Some(_) => Err(JsonErr::custom("Invalid 'meta'")),
517+
None => Ok(Column {
518+
name: name.value.clone(),
519+
meta: None,
520+
}),
521+
},
522+
None => Err(JsonErr::custom("Missing or invalid 'name'")),
523+
},
524+
_ => Err(JsonErr::custom("Invalid column type, expected a Dict")),
525+
})
526+
.collect()
527+
}
528+
529+
fn parse_grid_rows(rows: &List) -> Result<Vec<Dict>, JsonErr> {
530+
rows.iter()
531+
.map(|row| match row {
532+
HVal::Dict(row) => Ok(row.clone()),
533+
_ => Err(JsonErr::custom("Invalid row type, expected a Dict")),
534+
})
535+
.collect()
536+
}

src/haystack/encoding/zinc/decode/complex/grid.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44
55
use super::super::parser::ParserType;
66
use super::dict::parse_dict_parts;
7-
use crate::haystack::val::{Column, Dict, Grid, Value};
7+
use crate::{
8+
haystack::val::{Column, Dict, Grid, Value},
9+
val::VER,
10+
};
811
use std::io::{Error, Read};
912

1013
/// Parses a Zinc [Grid](crate::val::Grid)
@@ -55,7 +58,9 @@ fn parse_grid_content<'a, 'b: 'a, R: Read>(
5558

5659
parser.lexer.read()?;
5760

58-
let meta = parse_grid_meta(parser)?;
61+
let mut meta = parse_grid_meta(parser)?;
62+
meta.remove(VER);
63+
5964
parser.lexer.expect_char(b'\n', "Grid meta")?;
6065

6166
let columns = parse_grid_columns(parser)?;

src/haystack/val/grid.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ pub struct Column {
2121
/// The version of the grid format supported by this library
2222
pub const GRID_FORMAT_VERSION: &str = "3.0";
2323

24+
/// The grid meta version tag name.
25+
pub const VER: &str = "ver";
26+
2427
/// Haystack Grid
2528
///
2629
/// # Example
@@ -128,7 +131,7 @@ impl Grid {
128131
///```
129132
pub fn make_from_dicts_with_meta(rows: Vec<Dict>, meta: Dict) -> Self {
130133
let mut grid = Grid::make_from_dicts(rows);
131-
grid.meta = Some(meta);
134+
grid.meta = if meta.is_empty() { None } else { Some(meta) };
132135
grid
133136
}
134137

tests/json/test_grid.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ fn test_json_grid_empty_encode() {
2525
},
2626
];
2727
let grid = Value::make_grid(Grid {
28-
meta: Some(Dict::default()),
28+
meta: None,
2929
columns: vec![
3030
Column {
3131
name: "dis".into(),

0 commit comments

Comments
 (0)