1use rimloc_core::{Result, TransUnit};
2use std::io::Write;
3
4pub fn write_csv<W: Write>(writer: W, units: &[TransUnit], lang: Option<&str>) -> Result<()> {
5 let mut wtr = csv::Writer::from_writer(writer);
6
7 match lang {
9 Some(_) => wtr.write_record(["lang", "key", "source", "path", "line"])?,
10 None => wtr.write_record(["key", "source", "path", "line"])?,
11 }
12
13 for u in units {
14 let line_str = u.line.map(|l| l.to_string()).unwrap_or_default();
15 let path_str = u.path.to_string_lossy();
16 let source = u.source.as_deref().unwrap_or("");
17
18 match lang {
19 Some(l) => wtr.write_record([l, &u.key, source, &path_str, &line_str])?,
20 None => wtr.write_record([&u.key, source, &path_str, &line_str])?,
21 }
22 }
23
24 wtr.flush()?;
25 Ok(())
26}
27
28#[cfg(test)]
29mod tests {
30 use super::*;
31 use std::path::PathBuf;
32
33 fn unit(key: &str, src: &str) -> TransUnit {
34 TransUnit {
35 key: key.into(),
36 source: Some(src.into()),
37 path: PathBuf::from("/mod/Languages/English/Keyed/X.xml"),
38 line: Some(42),
39 }
40 }
41
42 #[test]
43 fn csv_without_lang_column() {
44 let units = vec![unit("A", "Hello"), unit("B", "World")];
45 let mut buf: Vec<u8> = Vec::new();
46 write_csv(&mut buf, &units, None).unwrap();
47 let s = String::from_utf8(buf).unwrap();
48
49 assert!(s
50 .lines()
51 .next()
52 .unwrap()
53 .starts_with("key,source,path,line"));
54 assert!(s.contains("A,Hello,/mod/Languages/English/Keyed/X.xml,42"));
55 }
56
57 #[test]
58 fn csv_with_lang_column() {
59 let units = vec![unit("A", "Hello")];
60 let mut buf: Vec<u8> = Vec::new();
61 write_csv(&mut buf, &units, Some("ru")).unwrap();
62 let s = String::from_utf8(buf).unwrap();
63
64 assert!(s
65 .lines()
66 .next()
67 .unwrap()
68 .starts_with("lang,key,source,path,line"));
69 assert!(s.contains("ru,A,Hello,/mod/Languages/English/Keyed/X.xml,42"));
70 }
71}