dbtin: add parser for double-colon-separated format (similar to the passwd format)
Dependencies
- [2]
VLUIVUU5initialize repository
Change contents
- edit in crates/zhed-misc-parsers/src/dbtin.rs at line 15
```or alternatively:```textPATH/TO/OBJECT:KEY1:VALUE1PATH/TO/OBJECT:KEY2:VALUE2 - edit in crates/zhed-misc-parsers/src/dbtin.rs at line 26
let mut it = s.lines().filter(|i| !i.trim().is_empty()).peekable();let i = it.peek()?;let dcl = i.find(':')?;// find out which type of dbtin dump we have hereif dcl != 0 && i[dcl + 1..].find(':').is_some() {// (OBJ:KEY:VALUE)+parse_colsv(it)} else {// :OBJ\n(KEY:VALUE)+parse_groups(it)}}fn parse_colsv<'a>(it: impl Iterator<Item = &'a str>) -> Option<Node<'a>> {let mut ret = Node::Branch(HashMap::new());for i in it {let dcl1 = i.find(':')?;if dcl1 == 0 {// format error, this indicates a group insteadreturn None;}let kvp = &i[dcl1 + 1..];let dcl2 = kvp.find(':')?;let (obj, key, value) = (&i[..dcl1], &kvp[..dcl2], &kvp[dcl2 + 1..]);let sel = ret.select(obj)?;if !final_leaf_push(sel, key, value) {return None;}}Some(ret)}fn parse_groups<'a>(it: impl Iterator<Item = &'a str>) -> Option<Node<'a>> { - edit in crates/zhed-misc-parsers/src/dbtin.rs at line 74
for i in s.lines() {if i.trim().is_empty() {continue;} - edit in crates/zhed-misc-parsers/src/dbtin.rs at line 75
for i in it { - edit in crates/zhed-misc-parsers/src/dbtin.rs at line 92
}fn final_leaf_push<'a>(sel: &mut HashMap<&'a str, Node<'a>>, key: &'a str, value: &'a str) -> bool {use std::collections::hash_map::Entry;match sel.entry(key) {Entry::Occupied(_) => return false,Entry::Vacant(vac) => vac.insert(Node::Leaf(value)),};true - replacement in crates/zhed-misc-parsers/src/dbtin.rs at line 104
fn push_to_leaves(&mut self, obj: &'a str, kvm: HashMap<&'a str, &'a str>) -> bool {let mut sel: &mut HashMap<&'a str, Node> = if let Node::Branch(ref mut b) = self {bfn branch_mut<'s>(&'s mut self) -> Option<&'s mut HashMap<&'a str, Node<'a>>> {if let Node::Branch(ref mut x) = self {Some(x) - replacement in crates/zhed-misc-parsers/src/dbtin.rs at line 108
return false;};for i in obj.split('/').filter(|i| !i.is_empty()) {if let Node::Branch(ref mut x) =sel.entry(i).or_insert_with(|| Node::Branch(HashMap::new())){sel = x;} else {return false;};None - edit in crates/zhed-misc-parsers/src/dbtin.rs at line 110
} - replacement in crates/zhed-misc-parsers/src/dbtin.rs at line 112
for (key, value) in kvm {use std::collections::hash_map::Entry;match sel.entry(key) {Entry::Occupied(_) => return false,Entry::Vacant(vac) => vac.insert(Node::Leaf(value)),};}fn select<'s>(&'s mut self, obj: &'a str) -> Option<&'s mut HashMap<&'a str, Node<'a>>> {obj.split('/').filter(|i| !i.is_empty()).try_fold(self.branch_mut()?, |sel, i| {sel.entry(i).or_insert_with(|| Node::Branch(HashMap::new())).branch_mut()})} - replacement in crates/zhed-misc-parsers/src/dbtin.rs at line 122
truefn push_to_leaves(&mut self, obj: &'a str, kvm: HashMap<&'a str, &'a str>) -> bool {if let Some(sel) = self.select(obj) {kvm.into_iter().all(|(key, value)| final_leaf_push(sel, key, value))} else {false} - replacement in crates/zhed-misc-parsers/src/dbtin.rs at line 135
#[test]fn ex_ok() {fn ex0() -> Node<'static> { - edit in crates/zhed-misc-parsers/src/dbtin.rs at line 158
Node::Branch(inner1)} - edit in crates/zhed-misc-parsers/src/dbtin.rs at line 162
#[test]fn ex0_groups() { - replacement in crates/zhed-misc-parsers/src/dbtin.rs at line 177
Some(Node::Branch(inner1))Some(ex0()));}#[test]fn ex0_colsv() {assert_eq!(parse(r#"Schule/Orga/Fach/ETH:trfull:EthikSchule/Orga/Fach/ETH:tanken:JaSchule/Orga/Fach/RUF:trfull:RufenSchule/Orga/Fach/RUF:tanken:NeinSchule/Orga:locan :bl uüpp"#),Some(ex0())