X-Git-Url: http://git.scottworley.com/tablify/blobdiff_plain/e8657dffc83621d84240320f5389b81ab8204c78..d22b2e05706f7a4367ac3df33d61383673724b8b:/src/lib.rs?ds=inline diff --git a/src/lib.rs b/src/lib.rs index bebbcf7..2dd3964 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -41,13 +41,19 @@ const FOOTER: &str = " #[derive(Debug, PartialEq, Eq, Hash)] struct Entry { col: String, - instance: String, + instance: Option, } impl From<&str> for Entry { fn from(value: &str) -> Entry { - Entry { - col: String::from(value), - instance: String::from(""), + match value.split_once(':') { + None => Entry { + col: String::from(value), + instance: None, + }, + Some((col, instance)) => Entry { + col: String::from(col.trim()), + instance: Some(String::from(instance.trim())), + }, } } } @@ -116,9 +122,15 @@ fn read_rows(input: impl std::io::Read) -> impl Iterator Vec<(usize, String)> { let mut counts: Vec<_> = rows .iter() - .flat_map(|r| r.entries.iter().collect::>().into_iter()) - .fold(HashMap::new(), |mut cs, e| { - cs.entry(String::from(&e.col)) + .flat_map(|r| { + r.entries + .iter() + .map(|e| &e.col) + .collect::>() + .into_iter() + }) + .fold(HashMap::new(), |mut cs, col| { + cs.entry(String::from(col)) .and_modify(|n| *n += 1) .or_insert(1); cs @@ -129,6 +141,12 @@ fn column_counts(rows: &[RowInput]) -> Vec<(usize, String)> { counts.sort(); counts } +fn column_order(rows: &[RowInput]) -> Vec { + column_counts(rows) + .into_iter() + .map(|(_, col)| col) + .collect() +} /// # Errors /// @@ -138,7 +156,7 @@ fn column_counts(rows: &[RowInput]) -> Vec<(usize, String)> { /// * an indented line with no preceding non-indented line pub fn tablify(input: impl std::io::Read) -> Result { let rows = read_rows(input).collect::, _>>()?; - let _columns = column_counts(&rows); + let _columns = column_order(&rows); Ok(String::from(HEADER) + "Hello, world!" + FOOTER) } @@ -146,6 +164,31 @@ pub fn tablify(input: impl std::io::Read) -> Result { mod tests { use super::*; + #[test] + fn test_parse_entry() { + assert_eq!( + Entry::from("foo"), + Entry { + col: String::from("foo"), + instance: None + } + ); + assert_eq!( + Entry::from("foo:bar"), + Entry { + col: String::from("foo"), + instance: Some(String::from("bar")) + } + ); + assert_eq!( + Entry::from("foo: bar"), + Entry { + col: String::from("foo"), + instance: Some(String::from("bar")) + } + ); + } + #[test] fn test_read_rows() { assert_eq!( @@ -266,5 +309,13 @@ mod tests { ), vec![(1, String::from("bar")), (2, String::from("baz"))] ); + assert_eq!( + column_counts( + &read_rows(&b"foo\n bar: 1\n bar: 2\n baz\n bar\nquux\n baz"[..]) + .collect::, _>>() + .unwrap() + ), + vec![(1, String::from("bar")), (2, String::from("baz"))] + ); } }