summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRyan Geary <rtgnj42@gmail.com>2020-06-17 20:50:49 -0400
committerRyan Geary <rtgnj42@gmail.com>2020-06-17 20:50:49 -0400
commit2ee77aa848be60acdf75b02cf2a8c0ff97196ad1 (patch)
tree477355a8b0917b0c68343e1e35256b5f3bc4a4cc
parent767b9303f218ae1c15f5dfbcc7b62c72983e5efb (diff)
Move backslash escaping to separate crate
-rw-r--r--Cargo.lock7
-rw-r--r--Cargo.toml1
-rw-r--r--src/escape.rs136
-rw-r--r--src/opt.rs3
-rw-r--r--src/parse.rs5
5 files changed, 14 insertions, 138 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 56a7d17..c27a0d9 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -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",
diff --git a/Cargo.toml b/Cargo.toml
index 5deeb81..4b99f4e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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'));
- }
- }
-}
diff --git a/src/opt.rs b/src/opt.rs
index 1eb08ee..94f1236 100644
--- a/src/opt.rs
+++ b/src/opt.rs
@@ -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;