use alloc::string::String;
use alloc::vec::Vec;
pub trait WtfEncoding {
type Unit: Copy + Ord + core::hash::Hash + core::fmt::Debug;
const NUL: Self::Unit;
fn encode_str(s: &str) -> Vec<Self::Unit>;
fn decode(units: &[Self::Unit]) -> Option<String>;
fn decode_lossy(units: &[Self::Unit]) -> String;
fn eq_str(units: &[Self::Unit], s: &str) -> bool {
units == Self::encode_str(s).as_slice()
}
fn debug_fmt(units: &[Self::Unit], f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:?}", Self::decode_lossy(units))
}
}
pub enum Wtf16 {}
impl WtfEncoding for Wtf16 {
type Unit = u16;
const NUL: u16 = 0;
fn encode_str(s: &str) -> Vec<u16> {
s.encode_utf16().collect()
}
fn decode(units: &[u16]) -> Option<String> {
String::from_utf16(units).ok()
}
fn decode_lossy(units: &[u16]) -> String {
String::from_utf16_lossy(units)
}
fn eq_str(units: &[u16], s: &str) -> bool {
units.iter().copied().eq(s.encode_utf16())
}
fn debug_fmt(units: &[u16], f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
use core::fmt::Write as _;
f.write_char('"')?;
for unit in core::char::decode_utf16(units.iter().copied()) {
match unit {
Ok('\'') => f.write_char('\'')?,
Ok(c) => {
for esc in c.escape_debug() {
f.write_char(esc)?;
}
}
Err(e) => write!(f, "\\u{{{:x}}}", e.unpaired_surrogate())?,
}
}
f.write_char('"')
}
}
pub enum Wtf8 {}
impl WtfEncoding for Wtf8 {
type Unit = u8;
const NUL: u8 = 0;
fn encode_str(s: &str) -> Vec<u8> {
s.as_bytes().to_vec()
}
fn decode(units: &[u8]) -> Option<String> {
core::str::from_utf8(units).ok().map(String::from)
}
fn decode_lossy(units: &[u8]) -> String {
String::from_utf8_lossy(units).into_owned()
}
fn eq_str(units: &[u8], s: &str) -> bool {
units == s.as_bytes()
}
fn debug_fmt(units: &[u8], f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
use core::fmt::Write as _;
f.write_char('"')?;
for chunk in units.utf8_chunks() {
for c in chunk.valid().chars() {
if c == '\'' {
f.write_char('\'')?;
} else {
for esc in c.escape_debug() {
f.write_char(esc)?;
}
}
}
for &b in chunk.invalid() {
write!(f, "\\x{b:02x}")?;
}
}
f.write_char('"')
}
}