#![cfg(all(feature = "std", unix))]
use crate::error::Error;
lazy_static! {
pub(crate) static ref UTF_8: Encoding = Encoding::from_bytes(b"UTF-8").unwrap();
}
static LATIN_1: &'static encoding_rs::Encoding = encoding_rs::WINDOWS_1252;
#[derive(Copy, Clone, Debug)]
pub(crate) struct Encoding(&'static encoding_rs::Encoding);
impl Encoding {
pub(crate) fn decode<'a>(&self, bytes: &'a [u8]) -> Result<String, Error> {
let (cow, _encoding, is_err) = self.0.decode(bytes);
if is_err {
return Err(Error::system_invalid_return(
"nl_langinfo",
format!(
"nl_langinfo unexpectedly returned data that could not be decoded \
using the proscribed encoding {}. the invalid data was {:?}.",
self.name(),
bytes
),
));
}
Ok(cow.into())
}
pub(crate) fn name(&self) -> &'static str {
self.0.name()
}
}
impl Encoding {
pub(crate) fn from_bytes(bytes: &[u8]) -> Result<Encoding, Error> {
if let Some(encoding) = encoding_rs::Encoding::for_label_no_replacement(bytes) {
return Ok(Encoding(encoding));
}
let encoding = match bytes {
b"" => LATIN_1,
b"Big5HKSCS" => encoding_rs::BIG5,
b"CP949" => encoding_rs::EUC_KR,
b"eucCN" => encoding_rs::GB18030,
b"eucJP" => encoding_rs::EUC_JP,
b"eucKR" => encoding_rs::EUC_KR,
b"ARMSCII-8" => LATIN_1,
b"CP1131" => LATIN_1,
b"ISCII-DEV" => LATIN_1,
b"PT154" => LATIN_1,
_ => {
let name = String::from_utf8_lossy(bytes);
return Err(Error::system_unsupported_encoding(name));
}
};
Ok(Encoding(encoding))
}
}