Crates.io | descape |
lib.rs | descape |
version | 2.0.3 |
source | src |
created_at | 2024-02-26 18:59:37.892957 |
updated_at | 2024-09-23 23:53:39.919538 |
description | Adds a single extension trait for &str to unescape any backslashes. |
homepage | |
repository | https://github.com/balt-dev/descape |
max_upload_size | |
id | 1154030 |
size | 37,775 |
Provides utilities for easily parsing escape sequences in a string, using alloc::borrow::Cow
to only borrow when needed.
This library supports many escape sequences:
\\a
-> \x07
\\b
-> \x08
\\t
-> \x09
\\n
-> \x0A
\\v
-> \x0B
\\f
-> \x0C
\\r
-> \x0D
\\e
-> \x1B
\\'
-> '
\\"
-> "
\\`
-> `
\\\\
-> \\
\\xNN
-> \xNN
\\o
-> \o
, for all octal digits o
\\oo
-> \oo
, for all octal digits o
\\ooo
-> \ooo
, for all octal digits o
\\uXXXX
-> \u{XXXX}
\\u{HEX}
-> \u{HEX}
Along with this, you can define your own custom escape handlers! See UnescapeExt::to_unescaped_with
for more information on that.
This crate supports no-std
.
Optionally, this crate has the std
and core_error
features,
to allow the error type of an invalid escape to implement the Error
trait.
std
uses std::error::Error
, and core_error
depends on core::error::Error
, which is stable on Rust 1.82.0 or greater.
let escaped = "Hello,\\nworld!".to_unescaped();
assert_eq!(
escaped.unwrap(),
Cow::Owned::<'_, str>("Hello,\nworld!".to_string())
);
let no_escapes = "No escapes here!".to_unescaped();
assert_eq!(
no_escapes.unwrap(),
Cow::Borrowed("No escapes here!")
);
// v invalid at index 7
let invalid_escape = r"Uh oh! \xJJ".to_unescaped();
assert_eq!(
invalid_escape.unwrap_err().index,
7
);
fn raw(idx: usize, chr: char, _: &mut CharIndices) -> Result<Option<char>, ()> {
Ok(Some(chr))
}
let escaped = r"\H\e\l\l\o \n \W\o\r\l\d";
let unescaped = escaped.to_unescaped_with(raw).expect("this is fine");
assert_eq!(unescaped, "Hello n World");
fn raw(idx: usize, chr: char, _: &mut CharIndices) -> Result<Option<char>, ()> {
Ok(None)
}
let escaped = r"What if I want a \nnewline?";
let unescaped = escaped.to_unescaped_with(raw).expect("this should work");
assert_eq!(unescaped, "What if I want a newline?");
fn rust_only(idx: usize, chr: char, iter: &mut CharIndices) -> Result<Option<char>, ()> {
match chr {
'a' | 'b' | 'v' | 'f' | 'e' | '`' => Err(()),
_ => descape::DefaultHandler.escape(idx, chr, iter)
}
}
r"This is \nfine".to_unescaped_with(rust_only).expect(r"\n is valid");
r"This is not \fine".to_unescaped_with(rust_only).expect_err(r"\f is invalid");