pub use percent_encoding::percent_decode;
use percent_encoding::{AsciiSet, NON_ALPHANUMERIC, percent_encode};
const FORM_URLENCODE_SET: &AsciiSet = &NON_ALPHANUMERIC
.remove(b'-')
.remove(b'_')
.remove(b'.')
.remove(b'~');
pub fn encode_url_owned(input: &str) -> String {
percent_encode(input.as_bytes(), FORM_URLENCODE_SET).to_string()
}
pub fn encode_url(input: &mut String) {
let encoded = encode_url_owned(input);
*input = encoded;
}
pub fn decode_url_owned(input: &str) -> String {
percent_decode(input.as_bytes())
.decode_utf8_lossy()
.into_owned()
}
pub fn decode_form_url_owned(input: &str) -> String {
let mut bytes = input.as_bytes().to_vec();
for b in bytes.iter_mut() {
if *b == b'+' {
*b = b' ';
}
}
percent_decode(&bytes).decode_utf8_lossy().into_owned()
}
pub fn decode_url(input: &mut String) {
let decoded = decode_url_owned(input);
*input = decoded;
}
pub fn needs_extended_encoding(s: &str) -> bool {
s.chars()
.any(|c| c > '\u{7F}' || c == '"' || c == '\\' || c == '%')
}
pub fn unescape_quoted_string(s: &str) -> String {
let mut result = String::with_capacity(s.len());
let mut chars = s.chars().peekable();
let mut in_quotes = false;
while let Some(c) = chars.next() {
match c {
'"' if !in_quotes => in_quotes = true,
'"' if in_quotes => in_quotes = false,
'\\' if in_quotes => {
if let Some(next) = chars.next() {
result.push(next);
}
}
_ if in_quotes => result.push(c),
_ => {} }
}
result
}
pub fn escape_quoted_string(s: &str) -> String {
let mut result = String::with_capacity(s.len() + 2);
for c in s.chars() {
if c == '"' || c == '\\' {
result.push('\\');
}
result.push(c);
}
result
}