#![doc = include_str!("../README.md")]
#![no_std]
use core::iter::{Iterator, FusedIterator, ExactSizeIterator};
#[inline]
pub const fn is_teletex_diacritic (c: u8) -> bool {
(c > 0xC0) && (c <= 0xCF)
}
pub const fn teletex_char_to_utf8_char (c: u8) -> char {
match c {
0xA4 => '$',
0xA6 => '#',
0xA8 => '¤', 0xB4 => '×', 0xB8 => '÷', 0xE0 => 'Ω', 0xE1 => 'Æ', 0xE2 => 'Ð', 0xE3 => 'ª', 0xE4 => 'Ħ', 0xE6 => 'IJ', 0xE7 => 'Ŀ', 0xE8 => 'Ł', 0xE9 => 'Ø', 0xEA => 'Œ', 0xEB => 'º', 0xEC => 'Þ', 0xED => 'Ŧ', 0xEE => 'Ŋ', 0xEF => 'ʼn', 0xF0 => 'ĸ', 0xF1 => 'æ', 0xF2 => 'đ', 0xF3 => 'ð', 0xF4 => 'ħ', 0xF5 => 'ı', 0xF6 => 'ij', 0xF7 => 'ŀ', 0xF8 => 'ł', 0xF9 => 'ø', 0xFA => 'œ', 0xFB => 'ß', 0xFC => 'þ', 0xFD => 'ŧ', 0xFE => 'ŋ',
0xC1 => '\u{0300}',
0xC2 => '\u{0301}',
0xC3 => '\u{0302}',
0xC4 => '\u{0303}',
0xC5 => '\u{0304}',
0xC6 => '\u{0306}',
0xC7 => '\u{0307}',
0xC8 => '\u{0308}',
0xC9 => '\u{0308}',
0xCA => '\u{030A}',
0xCB => '\u{0327}',
0xCC => '\u{0332}',
0xCD => '\u{030B}',
0xCE => '\u{0328}',
0xCF => '\u{030C}',
anything_else => if anything_else.is_ascii() {
anything_else as char
} else {
'\u{FFFD}' },
}
}
pub struct TeletexToUnicodeChars<'a> {
teletex: &'a [u8],
diacritic: Option<char>,
}
impl <'a> TeletexToUnicodeChars<'a> {
#[inline]
pub(crate) const fn new(teletex: &'a [u8]) -> TeletexToUnicodeChars<'a> {
TeletexToUnicodeChars{ teletex, diacritic: None }
}
}
const REPLACEMENT_CHAR: char = '\u{FFFD}';
impl <'a> Iterator for TeletexToUnicodeChars<'a> {
type Item = char;
fn next(&mut self) -> Option<Self::Item> {
if let Some(diac) = self.diacritic.take() {
return Some(diac);
}
let tb = *self.teletex.first()?;
self.teletex = &self.teletex[1..];
if !is_teletex_diacritic(tb) {
return Some(teletex_char_to_utf8_char(tb));
}
let tb2 = *self.teletex.first()?;
self.teletex = &self.teletex[1..];
if !tb2.is_ascii_alphabetic() {
return Some(REPLACEMENT_CHAR);
}
self.diacritic = Some(teletex_char_to_utf8_char(tb));
Some(teletex_char_to_utf8_char(tb2))
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.teletex.len() + if self.diacritic.is_some() { 1 } else { 0 };
(len, Some(len))
}
}
impl <'a> FusedIterator for TeletexToUnicodeChars<'a> {}
impl <'a> ExactSizeIterator for TeletexToUnicodeChars<'a> {}
#[inline]
pub const fn teletex_to_utf8 <'a> (bytes: &'a [u8]) -> TeletexToUnicodeChars<'a> {
TeletexToUnicodeChars::new(bytes)
}
#[cfg(test)]
mod tests {
extern crate alloc;
use super::teletex_to_utf8;
use alloc::string::String;
#[test]
fn it_translates_unequivalent_chars() {
let input = b"Big\xA4Money\xA4";
let output: String = teletex_to_utf8(input).collect();
assert_eq!(output.as_str(), "Big$Money$");
}
#[test]
fn it_transposes_and_translates_diacritics() {
let input = b"BigB\xC4o\xC5i";
let output: String = teletex_to_utf8(input).collect();
assert_eq!(output.as_str(), "BigBo\u{0303}i\u{0304}");
}
#[test]
fn it_decodes_an_empty_string() {
let input = b"";
let output: String = teletex_to_utf8(input).collect();
assert_eq!(output.as_str(), "");
}
}