use std::str::from_utf8;
use std::fmt::{self, Debug, Display};
use std::ops::Deref;
#[derive(PartialEq)]
pub struct MaybeStr([u8]);
impl MaybeStr {
pub fn from_bytes(bytes: &[u8]) -> &MaybeStr {
unsafe { &*((bytes as *const [u8]) as *const MaybeStr)}
}
pub fn as_bytes(&self) -> &[u8] {
self
}
pub fn to_maybe_string(&self) -> MaybeString {
MaybeString(self.as_bytes().to_owned())
}
pub fn to_lossy_string(&self) -> String {
String::from_utf8_lossy(self.as_bytes()).into_owned()
}
}
impl Debug for MaybeStr {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
if let Ok(string) = from_utf8(self.as_bytes()) {
write!(f, "{:?}", string)
} else {
write!(f, "{:?}<non-UTF-8 data: {:?}>", String::from_utf8_lossy(&self.as_bytes()), &self.as_bytes())
}
}
}
impl Display for MaybeStr {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
write!(f, "{}", String::from_utf8_lossy(&self.as_bytes()))
}
}
impl Deref for MaybeStr {
type Target = [u8];
fn deref(&self) -> &[u8] {
&self.0
}
}
#[derive(PartialEq)]
pub struct MaybeString(pub Vec<u8>);
impl MaybeString {
pub fn as_bytes(&self) -> &[u8] {
self
}
pub fn as_maybe_str(&self) -> &MaybeStr {
self
}
pub fn into_lossy_string(self) -> String {
match String::from_utf8(self.0) {
Ok(string) => string,
Err(err) => {
String::from_utf8_lossy(err.into_bytes().as_slice()).into_owned()
}
}
}
}
impl Deref for MaybeString {
type Target = MaybeStr;
fn deref(&self) -> &MaybeStr {
MaybeStr::from_bytes(self.0.as_slice())
}
}
impl Debug for MaybeString {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
write!(f, "{:?}", self.as_maybe_str())
}
}
impl Display for MaybeString {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
write!(f, "{}", self.as_maybe_str())
}
}