use std::collections::HashMap;
use crate::{response::mapping, DataType, Value};
use super::timed::Timed;
#[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize)]
pub struct Associative {
pub rows: Vec<HashMap<String, Value>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub time: Option<f64>,
pub types: HashMap<String, DataType>,
}
impl Timed for Associative {
fn time(&self) -> Option<f64> {
self.time
}
}
impl From<mapping::Standard> for Associative {
fn from(standard: mapping::Standard) -> Self {
let columns = standard.columns;
let mut v = Vec::new();
let mut hm_typ = HashMap::new();
if let Some(rows) = standard.values {
for row in rows {
let mut hm = HashMap::new();
for (idx, column) in columns.iter().enumerate() {
if let Some(value) = row.get(idx) {
let _ = hm.insert(column.to_string(), value.clone());
}
}
v.push(hm);
}
for (idx, column) in columns.iter().enumerate() {
if let Some(t) = standard.types.get(idx) {
let _ = hm_typ.insert(column.to_string(), *t);
}
}
}
Associative {
rows: v,
time: standard.time,
types: hm_typ,
}
}
}
#[cfg(test)]
mod tests {
use crate::{response::mapping, DataType};
use super::Associative;
#[test]
fn standard_to_associativ_test() {
let standard = mapping::Standard {
columns: vec!["id".to_string(), "val".to_string()],
time: None,
types: vec![DataType::Text, DataType::Text],
values: Some(vec![
vec!["123456".into(), "value".into()],
vec!["123456".into(), "value".into()],
vec!["123456".into(), "value".into()],
]),
};
let associative = Associative::from(standard.clone());
assert_eq!(associative.time, standard.time);
assert_eq!(associative.rows.len(), standard.values.unwrap().len());
let mut keys = associative.rows[0]
.keys()
.map(String::from)
.collect::<Vec<String>>();
keys.sort_unstable();
let mut columns = standard.columns;
columns.sort_unstable();
assert_eq!(keys, columns);
}
}