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 | |
parent | 767b9303f218ae1c15f5dfbcc7b62c72983e5efb (diff) |
Move backslash escaping to separate crate
-rw-r--r-- | Cargo.lock | 7 | ||||
-rw-r--r-- | Cargo.toml | 1 | ||||
-rw-r--r-- | src/escape.rs | 136 | ||||
-rw-r--r-- | src/opt.rs | 3 | ||||
-rw-r--r-- | src/parse.rs | 5 |
5 files changed, 14 insertions, 138 deletions
@@ -30,6 +30,12 @@ dependencies = [ ] [[package]] +name = "backslash" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35a89ea09f2c7f3c81711c0db7d389d86a9d66fa15a7067e6fd6dbef863ef786" + +[[package]] name = "bitflags" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -39,6 +45,7 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" name = "choose" version = "1.2.0" dependencies = [ + "backslash", "lazy_static", "regex", "structopt", @@ -19,3 +19,4 @@ exclude = [ structopt = "0.3" regex = "1" lazy_static = "1" +backslash = "0" 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; |