diff options
author | Ryan Geary <rtgnj42@gmail.com> | 2020-06-17 20:50:49 -0400 |
---|---|---|
committer | Ryan Geary <rtgnj42@gmail.com> | 2020-06-17 20:50:49 -0400 |
commit | 2ee77aa848be60acdf75b02cf2a8c0ff97196ad1 (patch) | |
tree | 477355a8b0917b0c68343e1e35256b5f3bc4a4cc /src | |
parent | 767b9303f218ae1c15f5dfbcc7b62c72983e5efb (diff) |
Move backslash escaping to separate crate
Diffstat (limited to 'src')
-rw-r--r-- | src/escape.rs | 136 | ||||
-rw-r--r-- | src/opt.rs | 3 | ||||
-rw-r--r-- | src/parse.rs | 5 |
3 files changed, 6 insertions, 138 deletions
diff --git a/src/escape.rs b/src/escape.rs index 9098746..8b13789 100644 --- a/src/escape.rs +++ b/src/escape.rs @@ -1,137 +1 @@ -pub fn process_escapes(input: &str) -> String { - if input.len() < 1 { - return String::from(input); - } - let mut v = Vec::from(input); - for i in 0..(v.len() - 1) { - if v[i] == '\\' as u8 && is_escapable(v[i + 1] as char) { - v.remove(i); - v[i] = char_to_escape_sequence(v[i] as char) as u8; - } - } - String::from_utf8(v).unwrap() -} - -fn char_to_escape_sequence(chr: char) -> char { - match chr { - 'n' => '\n', - 't' => '\t', - 'r' => '\r', - '\\' => '\\', - '0' => '\0', - _ => chr, - } -} - -fn is_escapable(chr: char) -> bool { - match chr { - 'n' | 't' | 'r' | '\\' | '0' => true, - _ => false, - } -} - -#[cfg(test)] -mod tests { - use super::*; - mod test_process_escapes { - use super::*; - - #[test] - fn test_newline() { - assert_eq!( - String::from("hello\nworld"), - process_escapes(r#"hello\nworld"#) - ); - } - - #[test] - fn test_carriage_return() { - assert_eq!( - String::from("hello\rworld"), - process_escapes(r#"hello\rworld"#) - ); - } - - #[test] - fn test_tab() { - assert_eq!( - String::from("hello\tworld"), - process_escapes(r#"hello\tworld"#) - ); - } - - #[test] - fn test_backslash() { - assert_eq!( - String::from("hello\\world"), - process_escapes(r#"hello\\world"#) - ); - } - - #[test] - fn test_null() { - assert_eq!( - String::from("hello\0world"), - process_escapes(r#"hello\0world"#) - ); - } - } - - mod test_char_to_escape_sequence { - use super::*; - #[test] - fn test_escape_n() { - assert_eq!('\n', char_to_escape_sequence('n')); - } - - #[test] - fn test_escape_t() { - assert_eq!('\t', char_to_escape_sequence('t')); - } - - #[test] - fn test_escape_r() { - assert_eq!('\r', char_to_escape_sequence('r')); - } - - #[test] - fn test_escape_backslash() { - assert_eq!('\\', char_to_escape_sequence('\\')); - } - - #[test] - fn test_escape_0() { - assert_eq!('\0', char_to_escape_sequence('0')); - } - } - - mod is_escapable_tests { - use super::*; - - #[test] - fn test_escape_n() { - assert!(is_escapable('n')); - } - - #[test] - fn test_escape_t() { - assert!(is_escapable('t')); - } - - #[test] - fn test_escape_r() { - assert!(is_escapable('r')); - } - - #[test] - fn test_escape_backslash() { - assert!(is_escapable('\\')); - } - - #[test] - fn test_escape_0() { - assert!(is_escapable('0')); - } - } -} @@ -2,7 +2,6 @@ use std::path::PathBuf; use structopt::StructOpt; use crate::choice::Choice; -use crate::escape; use crate::parse; #[derive(Debug, StructOpt)] @@ -38,7 +37,7 @@ pub struct Opt { pub one_indexed: bool, /// Specify output field separator - #[structopt(short, long, parse(from_str = escape::process_escapes))] + #[structopt(short, long, parse(from_str = parse::output_field_separator))] pub output_field_separator: Option<String>, /// Fields to print. Either a, a:b, a..b, or a..=b, where a and b are integers. The beginning diff --git a/src/parse.rs b/src/parse.rs index 17b5bfa..868da96 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -1,3 +1,4 @@ +use backslash::escape_ascii; use regex::Regex; use crate::choice::{Choice, ChoiceKind}; @@ -60,6 +61,10 @@ pub fn choice(src: &str) -> Result<Choice, ParseError> { return Ok(Choice::new(start, end, kind)); } +pub fn output_field_separator(src: &str) -> String { + escape_ascii(src).unwrap() +} + #[cfg(test)] mod tests { use crate::parse; |