pub(crate) mod check_lines;
pub(crate) mod counts;
pub(crate) fn pick_column(line: &str, column: usize) -> Option<&str> {
if column == 0 {
return None;
}
line.split(',').nth(column - 1)
}
pub(crate) fn json_escape(s: &str) -> String {
let mut out = String::with_capacity(s.len() + 2);
out.push('"');
for c in s.chars() {
match c {
'"' => out.push_str("\\\""),
'\\' => out.push_str("\\\\"),
'\n' => out.push_str("\\n"),
'\r' => out.push_str("\\r"),
'\t' => out.push_str("\\t"),
c if (c as u32) < 0x20 => {
out.push_str(&format!("\\u{:04x}", c as u32));
}
c => out.push(c),
}
}
out.push('"');
out
}
pub(crate) fn tsv_escape(s: &str) -> String {
s.replace(['\t', '\n', '\r'], " ")
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn pick_column_basic() {
assert_eq!(pick_column("a,b,c", 1), Some("a"));
assert_eq!(pick_column("a,b,c", 2), Some("b"));
assert_eq!(pick_column("a,b,c", 3), Some("c"));
assert_eq!(pick_column("a,b,c", 4), None);
assert_eq!(pick_column("a,b,c", 0), None);
assert_eq!(pick_column("", 1), Some(""));
}
#[test]
fn json_escape_specials() {
assert_eq!(json_escape(""), r#""""#);
assert_eq!(json_escape("abc"), r#""abc""#);
assert_eq!(json_escape(r#"a"b"#), r#""a\"b""#);
assert_eq!(json_escape("a\\b"), r#""a\\b""#);
assert_eq!(json_escape("a\nb"), r#""a\nb""#);
assert_eq!(json_escape("a\tb"), r#""a\tb""#);
assert_eq!(json_escape("\x01"), r#""\u0001""#);
}
#[test]
fn tsv_escape_basic() {
assert_eq!(tsv_escape("abc"), "abc");
assert_eq!(tsv_escape("a\tb"), "a b");
assert_eq!(tsv_escape("a\nb"), "a b");
assert_eq!(tsv_escape("a\rb"), "a b");
}
}