use std::io::Read; pub fn new(s: S) -> Vec { parse(from_string(s.to_string())) } fn from_string(s: String) -> String { match std::fs::File::open(s.clone()) { Ok(mut reader) => { let mut content = String::new(); reader .read_to_string(&mut content) .expect(format!("failed to read {}", s).as_ref()); content } Err(_) => s, } } fn parse(s: String) -> Vec { let s = s .split("\n") .filter(|x: &&str| { !x // doesnt start with # .split_whitespace() .collect::>() .join("") .starts_with("#") }) .map(|x| { x.split("#") .take(1) // drop after # .collect::>() .join("") .split_whitespace() .collect::>() .join(" ") }) .collect::>() .join("\n"); let mut channels = vec![]; let lines = s.split("\n").collect::>(); let mut j = 0; for i in 0..lines.len() { match lines[i] { "" => { j = 0; } _ => { while channels.len() <= j { channels.push("".to_string()); } channels[{ let tmp = j; j += 1; tmp }] += &(" ".to_string() + lines[i]); } }; } channels .iter() .map(|x| x.split_whitespace().collect::>().join(" ")) .collect() } #[cfg(test)] mod test { #[test] fn test_string() { assert_eq!(super::new("a b c")[0], "a b c".to_string()); assert_eq!(super::new("a b c".to_string())[0], "a b c".to_string()); } #[test] fn test_single_line_file() { assert_eq!( super::new("src/testdata/single_line_file.txt")[0], "a b c".to_string() ); } #[test] fn test_two_channels_one_bar() { assert_eq!( super::new("src/testdata/two_channels_one_bar.txt")[0], "2*a 2*b 2*c".to_string() ); assert_eq!( super::new("src/testdata/two_channels_one_bar.txt")[1], ". a5 . b5 . c5".to_string() ); } #[test] fn test_two_channels_two_bars() { assert_eq!( super::new("src/testdata/two_channels_two_bars.txt")[0], "a b c d e f".to_string() ); assert_eq!( super::new("src/testdata/two_channels_two_bars.txt")[1], "2*a 2*b 2*c 2*d 2*e 2*f".to_string() ); } #[test] fn drop_comment_lines() { assert_eq!( super::new("# hello\n # world\na b c")[0], "a b c".to_string() ); } #[test] fn drop_comment_trailer() { assert_eq!(super::new("a b c # hello world")[0], "a b c".to_string()); } }