use crate::report::{ListPatch, ReportOverride};
use toml::{Table, Value};
const LIST_OP_KEYS: [&str; 7] = [
"add", "remove", "replace", "prepend", "clear", "after", "before",
];
pub fn is_list_op_table(t: &Table) -> bool {
LIST_OP_KEYS.iter().any(|k| t.contains_key(*k))
}
pub fn patch_value_list(base: Vec<Value>, ov: &Value) -> Vec<Value> {
let strs: Option<Vec<String>> = base
.iter()
.map(|v| v.as_str().map(str::to_string))
.collect();
match strs {
Some(strs) => list_patch(ov)
.apply(&strs)
.into_iter()
.map(Value::String)
.collect(),
None => base,
}
}
pub fn report_override(cfg: &Table) -> ReportOverride {
cfg.get("report")
.and_then(Value::as_table)
.map(report_override_section)
.unwrap_or_default()
}
pub fn report_override_section(report: &Table) -> ReportOverride {
let patch = |key: &str| report.get(key).map(list_patch).unwrap_or_default();
ReportOverride {
columns: patch("columns"),
card: patch("card"),
stats: patch("stats"),
size: patch("size"),
filter: patch("filter"),
}
}
fn value_strs(v: Option<&Value>) -> Vec<String> {
v.and_then(Value::as_array)
.map(|a| {
a.iter()
.filter_map(|x| x.as_str().map(str::to_string))
.collect()
})
.unwrap_or_default()
}
fn list_patch(v: &Value) -> ListPatch {
match v {
Value::Array(a) => ListPatch {
replace_all: Some(
a.iter()
.filter_map(|x| x.as_str().map(str::to_string))
.collect(),
),
..Default::default()
},
Value::Table(t) => ListPatch {
replace_all: None,
clear: t.get("clear").and_then(Value::as_bool).unwrap_or(false),
remove: value_strs(t.get("remove")),
replace: t
.get("replace")
.and_then(Value::as_table)
.map(|rt| {
rt.iter()
.filter_map(|(k, val)| val.as_str().map(|s| (k.clone(), s.to_string())))
.collect()
})
.unwrap_or_default(),
after: anchor_pairs(t.get("after")),
before: anchor_pairs(t.get("before")),
prepend: value_strs(t.get("prepend")),
add: value_strs(t.get("add")),
},
_ => ListPatch::default(),
}
}
fn anchor_pairs(v: Option<&Value>) -> Vec<(String, Vec<String>)> {
v.and_then(Value::as_table)
.map(|t| {
t.iter()
.map(|(anchor, items)| (anchor.clone(), value_strs(Some(items))))
.collect()
})
.unwrap_or_default()
}
#[cfg(test)]
#[path = "list_override_test.rs"]
mod tests;