put diary date parser into yz-diary-date; improve dbtin parser, return HashMap
Dependencies
- [2]
PIAOZYFBdbtin: add parser for double-colon-separated format (similar to the passwd format) - [3]
5OQGNADFadd tgs support to zhed-misc-parsers - [4]
V4EAN7NNmove some stuff around; more packlist stuff - [5]
VLUIVUU5initialize repository - [6]
BUI22CYQ+zhed-packlist
Change contents
- file deletion: date.rs
use chrono::NaiveDate;use std::path::Path;fn fti_digits(s: &str) -> bool {s.len() >= 2 && s.chars().take(2).all(|i| i.is_ascii_digit())}pub fn parse_diary_date(par: &str, fin: &str) -> Option<NaiveDate> {if !fti_digits(fin) || par.len() < 4 {return None;}let y = par.parse::<i32>().ok()?;let m = fin[..2].parse::<u32>().unwrap();// verify the day infolet mut dayinf = &fin[2..];if dayinf.starts_with(|i| matches!(i, '-' | '_')) {dayinf = &dayinf[1..];}if !fti_digits(dayinf) {return None;}let d = dayinf[..2].parse::<u32>().unwrap();chrono::NaiveDate::from_ymd_opt(y, m, d)}/// tries to parse a diary entry path to extract the reference date/// should be usually given a path containing at least 2 componentspub fn parse_diary_date_from_path(x: &Path) -> Option<NaiveDate> {let mut fin = x;let mut fins = fin.file_name()?.to_str()?;// we allow 1 additional path component after the date partif !fti_digits(fins) {fin = x.parent()?;fins = fin.file_name()?.to_str()?;if !fti_digits(fins) {return None;}}let par = fin.parent()?.file_name()?.to_str()?;parse_diary_date(par, fins)}#[cfg(test)]mod tests {use super::*;#[test]fn diary_standard() {assert_eq!(parse_diary_date_from_path(Path::new("201/01_01")), None);assert_eq!(parse_diary_date_from_path(Path::new("2016/0")), None);assert_eq!(parse_diary_date_from_path(Path::new("2016/08_28")),Some(NaiveDate::from_ymd(2016, 08, 28)));assert_eq!(parse_diary_date_from_path(Path::new("teller/2016/08_28")),Some(NaiveDate::from_ymd(2016, 08, 28)));assert_eq!(parse_diary_date_from_path(Path::new("teller/2016/08_28nox/fluppig.jpg")),Some(NaiveDate::from_ymd(2016, 08, 28)));assert_eq!(parse_diary_date_from_path(Path::new("/blog/2017/1124y_vf.html")),Some(NaiveDate::from_ymd(2017, 11, 24)));}} - replacement in crates/zhed-misc-parsers/src/tgs.rs at line 17
ret.insert(&x[..p], vec![x[p+2..].trim_start()]);ret.insert(&x[..p], vec![x[p + 2..].trim_start()]); - replacement in crates/zhed-misc-parsers/src/tgs.rs at line 89
assert_eq!(parse(r#"assert_eq!(parse(r#" - replacement in crates/zhed-misc-parsers/src/tgs.rs at line 112
"#, &trtab), res);"#,&trtab),res); - edit in crates/zhed-misc-parsers/src/lib.rs at line 1
mod date;pub use crate::date::*; - replacement in crates/zhed-misc-parsers/src/lib.rs at line 5
pub use crate::tgs::{parse as parse_tgs};[3.2880]pub use crate::tgs::parse as parse_tgs; - edit in crates/zhed-misc-parsers/src/dbtin.rs at line 2
type Branch<'a> = HashMap<&'a str, Node<'a>>; - replacement in crates/zhed-misc-parsers/src/dbtin.rs at line 7
Branch(HashMap<&'a str, Node<'a>>),Branch(Branch<'a>), - replacement in crates/zhed-misc-parsers/src/dbtin.rs at line 27
pub fn parse(s: &str) -> Option<Node<'_>> {pub fn parse(s: &str) -> Option<Branch<'_>> { - replacement in crates/zhed-misc-parsers/src/dbtin.rs at line 42
fn parse_colsv<'a>(it: impl Iterator<Item = &'a str>) -> Option<Node<'a>> {let mut ret = Node::Branch(HashMap::new());fn parse_colsv<'a>(it: impl Iterator<Item = &'a str>) -> Option<Branch<'a>> {let mut ret = HashMap::new(); - replacement in crates/zhed-misc-parsers/src/dbtin.rs at line 54
let sel = ret.select(obj)?;let sel = select(&mut ret, obj)?; - replacement in crates/zhed-misc-parsers/src/dbtin.rs at line 63
fn parse_groups<'a>(it: impl Iterator<Item = &'a str>) -> Option<Node<'a>> {let mut ret = Node::Branch(HashMap::new());let mut selobj = None;#[derive(Default)]struct GroupParser<'a> {ret: Branch<'a>,selobj: Option<(&'a str, HashMap<&'a str, &'a str>)>,} - replacement in crates/zhed-misc-parsers/src/dbtin.rs at line 69
macro_rules! finish_selobj {() => {{if let Some((oname, okvm)) = selobj.take() {if !ret.push_to_leaves(oname, okvm) {return None;}}}};}fn parse_groups<'a>(it: impl Iterator<Item = &'a str>) -> Option<Branch<'a>> {let mut gp = GroupParser::default(); - replacement in crates/zhed-misc-parsers/src/dbtin.rs at line 77
finish_selobj!();selobj = Some((&i[1..], HashMap::new()));} else if let Some((_, ref mut kvm)) = &mut selobj {if !gp.finish_selobj() {return None;}gp.selobj = Some((&i[1..], HashMap::new()));} else if let Some((_, ref mut kvm)) = &mut gp.selobj { - replacement in crates/zhed-misc-parsers/src/dbtin.rs at line 89
finish_selobj!();Some(ret)if gp.finish_selobj() {Some(gp.ret)} else {None} - replacement in crates/zhed-misc-parsers/src/dbtin.rs at line 96
fn final_leaf_push<'a>(sel: &mut HashMap<&'a str, Node<'a>>, key: &'a str, value: &'a str) -> bool {impl<'a> GroupParser<'a> {fn finish_selobj(&mut self) -> bool {if let Some((oname, okvm)) = self.selobj.take() {if let Some(sel) = select(&mut self.ret, oname) {okvm.into_iter().all(|(key, value)| final_leaf_push(sel, key, value))} else {false}} else {true}}}fn final_leaf_push<'a>(sel: &mut Branch<'a>, key: &'a str, value: &'a str) -> bool { - edit in crates/zhed-misc-parsers/src/dbtin.rs at line 118
}fn select<'s, 'a>(ret: &'s mut Branch<'a>, obj: &'a str) -> Option<&'s mut Branch<'a>> {obj.split('/').filter(|i| !i.is_empty()).try_fold(ret, |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 131
fn branch_mut<'s>(&'s mut self) -> Option<&'s mut HashMap<&'a str, Node<'a>>> {fn branch_mut<'s>(&'s mut self) -> Option<&'s mut Branch<'a>> { - edit in crates/zhed-misc-parsers/src/dbtin.rs at line 136[2.1595]→[5.3746:3756](∅→∅),[5.3746]→[5.3746:3756](∅→∅),[5.3756]→[2.1596:1602](∅→∅),[2.1602]→[5.3756:3757](∅→∅),[5.3756]→[5.3756:3757](∅→∅),[5.3757]→[2.1603:1965](∅→∅),[2.1965]→[5.4023:4024](∅→∅),[5.4023]→[5.4023:4024](∅→∅),[5.4024]→[2.1966:2234](∅→∅)
}}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()})}fn 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 144
fn ex0() -> Node<'static> {fn ex0() -> HashMap<&'static str, Node<'static>> { - replacement in crates/zhed-misc-parsers/src/dbtin.rs at line 167
Node::Branch(inner1)inner1 - edit in crates/zhed-misc-parsers/Cargo.toml at line 9
[dependencies.chrono]version = "0.4"default-features = false - edit in Cargo.lock at line 145[5.3910]→[5.3910:3927](∅→∅),[5.3927]→[4.12211:12222](∅→∅),[4.12222]→[5.3941:3943](∅→∅),[5.3941]→[5.3941:3943](∅→∅)
dependencies = ["chrono",]