use crate::encoding::sealed::Sealed;
use crate::encoding::{AlwaysValid, NullTerminable, ValidateError};
use crate::{Encoding, Str};
#[cfg(feature = "rand")]
use rand::distr::Distribution;
#[cfg(feature = "rand")]
use rand::Rng;
const DECODE_MAP_ROMAN: [char; 128] = [
'Ä', 'Å', 'Ç', 'É', 'Ñ', 'Ö', 'Ü', 'á', 'à', 'â', 'ä', 'ã', 'å', 'ç', 'é', 'è', 'ê', 'ë', 'í',
'ì', 'î', 'ï', 'ñ', 'ó', 'ò', 'ô', 'ö', 'õ', 'ú', 'ù', 'û', 'ü', '†', '°', '¢', '£', '§', '•',
'¶', 'ß', '®', '©', '™', '´', '¨', '≠', 'Æ', 'Ø', '∞', '±', '≤', '≥', '¥', 'µ', '∂', '∑', '∏',
'π', '∫', 'ª', 'º', 'Ω', 'æ', 'ø', '¿', '¡', '¬', '√', 'ƒ', '≈', '∆', '«', '»', '…',
'\u{00A0}', 'À', 'Ã', 'Õ', 'Œ', 'œ', '–', '—', '“', '”', '‘', '’', '÷', '◊', 'ÿ', 'Ÿ', '⁄',
'€', '‹', '›', 'fi', 'fl', '‡', '·', '‚', '„', '‰', 'Â', 'Ê', 'Á', 'Ë', 'È', 'Í', 'Î', 'Ï', 'Ì',
'Ó', 'Ô', '\u{F8FF}', 'Ò', 'Ú', 'Û', 'Ù', 'ı', 'ˆ', '˜', '¯', '˘', '˙', '˚', '¸', '˝', '˛',
'ˇ',
];
#[non_exhaustive]
#[derive(Default)]
pub struct MacRoman;
impl Sealed for MacRoman {}
impl Encoding for MacRoman {
const REPLACEMENT: char = '?';
const MAX_LEN: usize = 1;
type Bytes = u8;
fn shorthand() -> &'static str {
"mac_roman"
}
fn validate(_: &[u8]) -> Result<(), ValidateError> {
Ok(())
}
fn encode_char(c: char) -> Option<Self::Bytes> {
if (..0x80).contains(&(c as u32)) {
Some(c as u8)
} else {
let pos = DECODE_MAP_ROMAN.iter().position(|v| *v == c)? as u8;
Some(pos + 0x80)
}
}
fn decode_char(str: &Str<Self>) -> (char, &Str<Self>) {
let b = str.as_bytes()[0];
if (..0x80).contains(&b) {
(b as char, &str[1..])
} else {
(DECODE_MAP_ROMAN[b as usize - 0x80], &str[1..])
}
}
fn char_bound(_: &Str<Self>, _: usize) -> bool {
true
}
fn char_len(c: char) -> usize {
if (c as u32) < 0x80 || DECODE_MAP_ROMAN.contains(&c) {
1
} else {
0
}
}
}
impl NullTerminable for MacRoman {}
impl AlwaysValid for MacRoman {}
#[cfg(feature = "rand")]
impl Distribution<char> for MacRoman {
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> char {
let c = rng.random::<u8>();
if c <= 0x7F {
char::from(c)
} else {
DECODE_MAP_ROMAN[(c - 0x80) as usize]
}
}
}