mirror of
https://github.com/theryangeary/choose
synced 2024-11-10 05:24:13 +00:00
Move backslash escaping to separate crate
This commit is contained in:
parent
767b9303f2
commit
2ee77aa848
5 changed files with 14 additions and 138 deletions
7
Cargo.lock
generated
7
Cargo.lock
generated
|
@ -29,6 +29,12 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "backslash"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "35a89ea09f2c7f3c81711c0db7d389d86a9d66fa15a7067e6fd6dbef863ef786"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "1.2.1"
|
version = "1.2.1"
|
||||||
|
@ -39,6 +45,7 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||||
name = "choose"
|
name = "choose"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"backslash",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"regex",
|
"regex",
|
||||||
"structopt",
|
"structopt",
|
||||||
|
|
|
@ -19,3 +19,4 @@ exclude = [
|
||||||
structopt = "0.3"
|
structopt = "0.3"
|
||||||
regex = "1"
|
regex = "1"
|
||||||
lazy_static = "1"
|
lazy_static = "1"
|
||||||
|
backslash = "0"
|
||||||
|
|
136
src/escape.rs
136
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 structopt::StructOpt;
|
||||||
|
|
||||||
use crate::choice::Choice;
|
use crate::choice::Choice;
|
||||||
use crate::escape;
|
|
||||||
use crate::parse;
|
use crate::parse;
|
||||||
|
|
||||||
#[derive(Debug, StructOpt)]
|
#[derive(Debug, StructOpt)]
|
||||||
|
@ -38,7 +37,7 @@ pub struct Opt {
|
||||||
pub one_indexed: bool,
|
pub one_indexed: bool,
|
||||||
|
|
||||||
/// Specify output field separator
|
/// 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>,
|
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
|
/// Fields to print. Either a, a:b, a..b, or a..=b, where a and b are integers. The beginning
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use backslash::escape_ascii;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
|
||||||
use crate::choice::{Choice, ChoiceKind};
|
use crate::choice::{Choice, ChoiceKind};
|
||||||
|
@ -60,6 +61,10 @@ pub fn choice(src: &str) -> Result<Choice, ParseError> {
|
||||||
return Ok(Choice::new(start, end, kind));
|
return Ok(Choice::new(start, end, kind));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn output_field_separator(src: &str) -> String {
|
||||||
|
escape_ascii(src).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::parse;
|
use crate::parse;
|
||||||
|
|
Loading…
Reference in a new issue