use std::error::Error;
use std::fmt;
use std::str::Utf8Error;
use std::string::FromUtf8Error;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum TextDecodeError {
InvalidUtf8 {
valid_up_to: usize,
error_len: Option<usize>,
},
}
impl fmt::Display for TextDecodeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::InvalidUtf8 {
valid_up_to,
error_len: Some(error_len),
} => write!(
f,
"text input contains invalid UTF-8 sequence of length {error_len} after byte {valid_up_to}"
),
Self::InvalidUtf8 {
valid_up_to,
error_len: None,
} => write!(
f,
"text input contains incomplete UTF-8 sequence after byte {valid_up_to}"
),
}
}
}
impl Error for TextDecodeError {}
impl From<Utf8Error> for TextDecodeError {
fn from(error: Utf8Error) -> Self {
Self::InvalidUtf8 {
valid_up_to: error.valid_up_to(),
error_len: error.error_len(),
}
}
}
impl From<FromUtf8Error> for TextDecodeError {
fn from(error: FromUtf8Error) -> Self {
error.utf8_error().into()
}
}
#[must_use]
pub fn encode_utf8_text(text: impl AsRef<str>) -> Vec<u8> {
text.as_ref().as_bytes().to_vec()
}
pub fn decode_utf8_text(bytes: impl Into<Vec<u8>>) -> Result<String, TextDecodeError> {
String::from_utf8(bytes.into()).map_err(Into::into)
}
#[must_use]
pub fn decode_utf8_text_lossy(bytes: impl AsRef<[u8]>) -> String {
String::from_utf8_lossy(bytes.as_ref()).into_owned()
}