use crate::{
Charset,
CharsetCodec,
CharsetDecodeError,
CharsetDecodeErrorKind,
CharsetDecodeResult,
CharsetEncodeError,
CharsetEncodeErrorKind,
CharsetEncodeResult,
DecodeStatus,
Unicode,
};
#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
pub struct Latin1Codec;
impl Latin1Codec {
#[must_use]
#[inline]
pub const fn charset(self) -> Charset {
Charset::ISO_8859_1
}
#[must_use]
#[inline]
pub const fn max_units_per_char(self) -> usize {
1
}
}
impl CharsetCodec for Latin1Codec {
type Unit = u8;
#[inline]
fn charset(&self) -> Charset {
Charset::ISO_8859_1
}
#[inline]
fn max_units_per_char(&self) -> usize {
1
}
#[inline]
fn decode_one(&self, input: &[u8], index: usize) -> CharsetDecodeResult<DecodeStatus> {
if index > input.len() {
let kind = CharsetDecodeErrorKind::MalformedSequence { value: None };
return Err(CharsetDecodeError::new(Charset::ISO_8859_1, kind, index));
}
if index == input.len() {
return Ok(DecodeStatus::NeedMore {
required: index + 1,
available: 0,
});
}
let value = input[index] as u32;
Ok(DecodeStatus::Complete {
value: Unicode::to_char(value).expect("valid Latin-1 byte decodes to Unicode scalar"),
consumed: 1,
})
}
#[inline]
fn encode_one(&self, ch: char, output: &mut [u8], index: usize) -> CharsetEncodeResult<usize> {
if index >= output.len() {
let kind = CharsetEncodeErrorKind::BufferTooSmall {
required: index + 1,
available: 0,
};
return Err(CharsetEncodeError::new(Charset::ISO_8859_1, kind, index));
}
let value = ch as u32;
if value > Unicode::LATIN1_MAX {
let kind = CharsetEncodeErrorKind::UnmappableCharacter { value };
return Err(CharsetEncodeError::new(Charset::ISO_8859_1, kind, index));
}
output[index] = value as u8;
Ok(1)
}
}