#[cfg(test)]
extern crate alloc;
#[cfg(test)]
use alloc::string::String;
use core::fmt::{Result, Write};
use oxiplate_traits::Escaper;
#[allow(non_camel_case_types)]
pub enum JsonEscaper {
substring,
}
impl Escaper for JsonEscaper {
const DEFAULT: Self = Self::substring;
#[inline]
fn escape<W: Write + ?Sized>(&self, f: &mut W, value: &str) -> Result {
match self {
Self::substring => escape_substring(f, value),
}
}
}
#[inline]
pub fn escape_substring<W: Write + ?Sized>(f: &mut W, value: &'_ str) -> Result {
for character in value.chars() {
match character {
'"' => f.write_str(r#"\""#)?,
'\\' => f.write_str(r"\\")?,
'\u{0000}'..='\u{001F}' => write!(f, "\\u{:04x}", character as u32)?,
_ => f.write_char(character)?,
}
}
Ok(())
}
#[test]
fn test_escape_substring() {
fn escape(raw: &str) -> String {
let mut escaped = String::with_capacity(raw.len());
escape_substring(&mut escaped, raw).unwrap();
escaped
}
assert_eq!(escape(r"\"), r"\\");
assert_eq!(escape(r#"""#), r#"\""#);
assert_eq!(escape(r#"\""#), r#"\\\""#);
assert_eq!(escape("\u{0000}"), r"\u0000");
assert_eq!(escape("\u{0001}"), r"\u0001");
}