Skip to content

Commit 1ef8d23

Browse files
committed
unescape whitespaces in join
1 parent a1896e5 commit 1ef8d23

File tree

1 file changed

+44
-3
lines changed

1 file changed

+44
-3
lines changed

src/main.rs

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,42 @@ fn apply_range<T: Clone>(items: &[T], range: &RangeSpec) -> Vec<T> {
314314
}
315315
}
316316

317+
/// Unescape \n, \t, \r, in argument strings
318+
fn unescape(s: &str) -> String {
319+
let mut out = String::new();
320+
let mut chars = s.chars().peekable();
321+
while let Some(c) = chars.next() {
322+
if c == '\\' {
323+
match chars.peek() {
324+
Some('n') => {
325+
out.push('\n');
326+
chars.next();
327+
}
328+
Some('t') => {
329+
out.push('\t');
330+
chars.next();
331+
}
332+
Some('r') => {
333+
out.push('\r');
334+
chars.next();
335+
}
336+
Some(&next) => {
337+
// Leave as-is: keep the backslash and the next char
338+
out.push('\\');
339+
out.push(next);
340+
chars.next();
341+
}
342+
None => {
343+
out.push('\\');
344+
}
345+
}
346+
} else {
347+
out.push(c);
348+
}
349+
}
350+
out
351+
}
352+
317353
fn apply_ops(input: &str, ops: &[StringOp]) -> Result<String, String> {
318354
let mut val = Value::Str(input.to_string());
319355
let mut last_split_sep: Option<String> = None;
@@ -351,7 +387,7 @@ fn apply_ops(input: &str, ops: &[StringOp]) -> Result<String, String> {
351387
},
352388
StringOp::Join { sep } => match &val {
353389
Value::List(list) => {
354-
val = Value::Str(list.join(sep));
390+
val = Value::Str(list.join(&unescape(sep)));
355391
}
356392
Value::Str(s) => {
357393
val = Value::Str(s.clone());
@@ -463,7 +499,7 @@ fn main() {
463499
let input = match cli.input {
464500
Some(input) => input,
465501
None => match read_stdin() {
466-
Ok(input) => input,
502+
Ok(input) => input.trim_end().to_string(),
467503
Err(e) => {
468504
eprintln!("Error: {}", e);
469505
std::process::exit(1);
@@ -484,6 +520,12 @@ fn main() {
484520
mod tests {
485521
use super::*;
486522

523+
#[test]
524+
fn test_join_newline() {
525+
let input = "a,b,c";
526+
assert_eq!(process(input, r"{split:,:..:join:\\n}").unwrap(), "a\nb\nc");
527+
}
528+
487529
#[test]
488530
fn test_split_index() {
489531
let input = "a,b,c";
@@ -921,4 +963,3 @@ mod tests {
921963
);
922964
}
923965
}
924-

0 commit comments

Comments
 (0)