use core::{
fmt,
hash::{
Hash,
Hasher,
},
};
use crate::ByteOrder;
#[derive(Clone, Copy, Debug)]
pub struct Charset {
id: &'static str,
name: &'static str,
aliases: &'static [&'static str],
}
impl Charset {
pub const ASCII: Self = Self::new("ascii", "ASCII", &["us-ascii"]);
pub const ISO_8859_1: Self = Self::new(
"iso-8859-1",
"ISO-8859-1",
&["latin1", "latin-1", "iso8859-1", "csisolatin1", "iso_8859-1"],
);
pub const UTF_8: Self = Self::new("utf-8", "UTF-8", &["utf8"]);
pub const UTF_16: Self = Self::new("utf-16", "UTF-16", &["utf16"]);
pub const UTF_16LE: Self = Self::new("utf-16le", "UTF-16LE", &["utf16le", "utf16_le", "utf_16_le"]);
pub const UTF_16BE: Self = Self::new("utf-16be", "UTF-16BE", &["utf16be", "utf16_be", "utf_16_be"]);
pub const UTF_32: Self = Self::new("utf-32", "UTF-32", &["utf32"]);
pub const UTF_32LE: Self = Self::new("utf-32le", "UTF-32LE", &["utf32le", "utf32_le", "utf_32_le"]);
pub const UTF_32BE: Self = Self::new("utf-32be", "UTF-32BE", &["utf32be", "utf32_be", "utf_32_be"]);
#[inline]
pub const fn new(id: &'static str, name: &'static str, aliases: &'static [&'static str]) -> Self {
Self { id, name, aliases }
}
#[inline]
pub const fn id(self) -> &'static str {
self.id
}
#[inline]
pub const fn name(self) -> &'static str {
self.name
}
#[inline]
pub const fn aliases(self) -> &'static [&'static str] {
self.aliases
}
#[inline]
pub const fn from_utf16_byte_order(byte_order: ByteOrder) -> Self {
match byte_order {
ByteOrder::LittleEndian => Self::UTF_16LE,
ByteOrder::BigEndian => Self::UTF_16BE,
}
}
#[inline]
pub const fn from_utf32_byte_order(byte_order: ByteOrder) -> Self {
match byte_order {
ByteOrder::LittleEndian => Self::UTF_32LE,
ByteOrder::BigEndian => Self::UTF_32BE,
}
}
#[inline]
pub fn byte_order(self) -> Option<ByteOrder> {
if self == Self::UTF_16LE || self == Self::UTF_32LE {
Some(ByteOrder::LittleEndian)
} else if self == Self::UTF_16BE || self == Self::UTF_32BE {
Some(ByteOrder::BigEndian)
} else {
None
}
}
#[inline]
pub fn matches_label(self, label: &str) -> bool {
if label.eq_ignore_ascii_case(self.id) || label.eq_ignore_ascii_case(self.name) {
return true;
}
self.aliases.iter().any(|alias| label.eq_ignore_ascii_case(alias))
}
}
impl PartialEq for Charset {
fn eq(&self, other: &Self) -> bool {
self.id == other.id
}
}
impl Eq for Charset {}
impl Hash for Charset {
fn hash<H>(&self, state: &mut H)
where
H: Hasher,
{
self.id.hash(state);
}
}
impl fmt::Display for Charset {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str(self.name())
}
}