diff --git a/redactor/src/main.rs b/redactor/src/main.rs index 222d7c6..8b58e44 100644 --- a/redactor/src/main.rs +++ b/redactor/src/main.rs @@ -1,6 +1,6 @@ -use std::io::{self, BufRead, Write}; +use std::io::{self, BufRead, Write, Result}; -pub fn masker(input: R, mut output: W, num_digits: usize) +pub fn redactor(input: R, mut output: W, num_digits: usize) where R: BufRead, W: Write, @@ -10,35 +10,41 @@ pub fn masker(input: R, mut output: W, num_digits: usize) mask.push('#'); } - - let mut redactions = Vec::new(); - for maybe_line in input.lines() { - let mut line = maybe_line.expect("Failed to read line"); - line.push('\n'); - let mut digits = 0; - redactions.clear(); - for (i, c) in line.chars().enumerate() { - if c.is_digit(10) { - digits += 1; - } - else { - if digits == num_digits { - redactions.push(i - digits); - } - digits = 0; - } - } + let mut line = fetch_next_line(maybe_line); + let sequences = find_digit_sequences(num_digits, &line); - for redaction in &redactions { - let redaction_end = redaction + num_digits; - line.replace_range(redaction..&redaction_end, &mask); + for sequence in &sequences { + let redaction_end = sequence + num_digits; + line.replace_range(sequence..&redaction_end, &mask); } write!(&mut output, "{}", line).expect("failed to write"); } () } +fn fetch_next_line(maybe_line: Result) -> String { + let mut line = maybe_line.expect("Failed to read line"); + line.push('\n'); + line +} + +fn find_digit_sequences(num_digits: usize, line: & String) -> Vec { + let mut sequences = Vec::new(); + let mut digits = 0; + for (i, c) in line.chars().enumerate() { + if c.is_digit(10) { + digits += 1; + } else { + if digits == num_digits { + sequences.push(i - digits); + } + digits = 0; + } + } + return sequences; +} + #[allow(dead_code)] fn main() { let stdio = io::stdin(); @@ -46,7 +52,7 @@ fn main() { let output = io::stdout(); - masker(input, output, 10); + redactor(input, output, 10); } #[cfg(test)] @@ -59,7 +65,7 @@ mod tests { let input = b"123\n"; let mut output = Vec::new(); - masker(&input[..], &mut output, 3); + redactor(&input[..], &mut output, 3); let output_str = String::from_utf8(output).expect("Not UTF-8"); @@ -70,7 +76,7 @@ mod tests { fn test_does_not_replace_non_digits() { let mut output = Vec::new(); - masker(&b"abc\n"[..], &mut output, 3); + redactor(&b"abc\n"[..], &mut output, 3); assert_eq!("abc\n", String::from_utf8(output).unwrap()); } @@ -79,7 +85,7 @@ mod tests { fn test_replaces_only_digits() { let mut output = Vec::new(); - masker(&b"a123b\n"[..], &mut output, 3); + redactor(&b"a123b\n"[..], &mut output, 3); assert_eq!("a###b\n", String::from_utf8(output).unwrap()); } @@ -88,7 +94,7 @@ mod tests { fn test_does_not_replace_fewer_digits_than_intended() { let mut output = Vec::new(); - masker(&b"a12bc\n"[..], &mut output, 3); + redactor(&b"a12bc\n"[..], &mut output, 3); assert_eq!("a12bc\n", String::from_utf8(output).unwrap()); } @@ -97,7 +103,7 @@ mod tests { fn test_does_not_replace_more_digits_than_intended() { let mut output = Vec::new(); - masker(&b"a1234bc\n"[..], &mut output, 3); + redactor(&b"a1234bc\n"[..], &mut output, 3); assert_eq!("a1234bc\n", String::from_utf8(output).unwrap()); } @@ -106,7 +112,7 @@ mod tests { fn test_replaces_multiple_occurrences_on_line() { let mut output = Vec::new(); - masker(&b"abc123de456fgh789xyz\n"[..], &mut output, 3); + redactor(&b"abc123de456fgh789xyz\n"[..], &mut output, 3); assert_eq!("abc###de###fgh###xyz\n", String::from_utf8(output).unwrap()); } @@ -115,7 +121,7 @@ mod tests { fn test_replaces_digits_at_start_of_line() { let mut output = Vec::new(); - masker(&b"123abc\n"[..], &mut output, 3); + redactor(&b"123abc\n"[..], &mut output, 3); assert_eq!("###abc\n", String::from_utf8(output).unwrap()); } @@ -124,7 +130,7 @@ mod tests { fn test_replaces_digits_at_end_of_line() { let mut output = Vec::new(); - masker(&b"abc123\n"[..], &mut output, 3); + redactor(&b"abc123\n"[..], &mut output, 3); assert_eq!("abc###\n", String::from_utf8(output).unwrap()); } @@ -133,7 +139,7 @@ mod tests { fn test_includes_fewer_that_intended_digits_at_end_of_line() { let mut output = Vec::new(); - masker(&b"abc12\n"[..], &mut output, 3); + redactor(&b"abc12\n"[..], &mut output, 3); assert_eq!("abc12\n", String::from_utf8(output).unwrap()); } @@ -142,7 +148,7 @@ mod tests { fn test_replaces_digits_on_multiple_lines() { let mut output = Vec::new(); - masker(&b"abc123\n456def789\n"[..], &mut output, 3); + redactor(&b"abc123\n456def789\n"[..], &mut output, 3); assert_eq!("abc###\n###def###\n", String::from_utf8(output).unwrap()); } @@ -151,7 +157,7 @@ mod tests { fn test_copes_with_multiple_runs_of_shorter_digits() { let mut output = Vec::new(); - masker(&b"abc12__34__56\n"[..], &mut output, 3); + redactor(&b"abc12__34__56\n"[..], &mut output, 3); assert_eq!("abc12__34__56\n", String::from_utf8(output).unwrap()); }