use std::error::Error;
use std::fmt;
include!(concat!(env!("OUT_DIR"), "/maps.rs"));
#[derive(Debug)]
pub struct TranslationError {
pub why: String,
}
impl fmt::Display for TranslationError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.why)
}
}
impl Error for TranslationError {}
pub fn encode_byte(value: u8) -> &'static str {
&BYTE_TO_EMOJI[value as usize]
}
pub fn decode_byte(input: &dyn AsRef<str>) -> Result<u8, TranslationError> {
let input_ref = input.as_ref();
let result = EMOJI_TO_BYTE.get(input_ref).ok_or_else(|| TranslationError {
why: format!("Cannot decode character {}", input_ref),
})?;
Ok(*result)
}
pub fn encode_string(input: &dyn AsRef<str>) -> String {
input.as_ref().bytes().map(encode_byte).collect::<String>()
}
pub fn decode_string(input: &dyn AsRef<str>) -> Result<String, TranslationError> {
let input = input.as_ref();
let result = {
let split_char = input
.chars()
.find(|&c| c == '\u{200b}' || c == 'π');
if let Some('\u{200b}') = split_char {
input.trim_end_matches("\u{200B}").split("\u{200B}")
} else {
input.trim_end_matches("ππ").split("ππ")
}
}
.map(|c| decode_byte(&c))
.collect::<Result<Vec<u8>, _>>()?;
Ok(String::from_utf8_lossy(&result).to_string())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_string_encode() {
assert_eq!(
encode_string(&"Test"),
"πβ¨β¨β¨,,,,ππππ,ππππβ¨π₯Ίππππβ¨π₯Ί,ππ"
);
}
#[test]
fn test_byte_encode() {
assert_eq!(encode_byte(b'h'), "ππ,,,,ππ",);
}
#[test]
fn test_char_decode() {
assert_eq!(decode_byte(&"ππ,,,,").unwrap(), b'h',);
}
#[test]
fn test_string_decode() {
assert_eq!(
decode_string(&"πβ¨β¨β¨,,,,\u{200B}ππ,\u{200B}ππβ¨π₯Ί\u{200B}ππβ¨π₯Ί,\u{200B}")
.unwrap(),
"Test"
);
assert_eq!(
decode_string(&"πβ¨β¨β¨,,,,ππππ,ππππβ¨π₯Ίππππβ¨π₯Ί,ππ").unwrap(),
"Test"
);
}
#[test]
fn test_unicode_string_encode() {
assert_eq!(
encode_string(&"π₯Ί"),
"π«β¨β¨β¨β¨ππππππ₯Ί,,,,πππππβ¨π₯Ίπππππβ¨β¨β¨π₯Ί,ππ"
);
assert_eq!(
encode_string(&"γγγ°γ"),
"π«β¨β¨π₯Ί,,ππππβ¨β¨π₯Ί,,,,ππππβ¨β¨β¨β¨πππ«β¨β¨π₯Ί,,ππ\
ππβ¨β¨β¨ππππβ¨β¨β¨β¨π₯Ί,,πππ«β¨β¨π₯Ί,,ππππβ¨β¨π₯Ί,,,,ππ\
πππβ¨β¨π₯Ί,πππ«β¨β¨π₯Ί,,ππππβ¨β¨β¨ππππβ¨β¨β¨β¨ππ"
);
}
#[test]
fn test_unicode_string_decode() {
assert_eq!(
decode_string(&"π«β¨β¨β¨β¨ππππππ₯Ί,,,,πππππβ¨π₯Ίπππππβ¨β¨β¨π₯Ί,ππ")
.unwrap(),
"π₯Ί",
);
assert_eq!(
decode_string(
&"π«β¨β¨π₯Ί,,ππππβ¨β¨π₯Ί,,,,ππππβ¨β¨β¨β¨πππ«β¨β¨π₯Ί,,ππ\
ππβ¨β¨β¨ππππβ¨β¨β¨β¨π₯Ί,,πππ«β¨β¨π₯Ί,,ππππβ¨β¨π₯Ί,,,,ππ\
πππβ¨β¨π₯Ί,πππ«β¨β¨π₯Ί,,ππππβ¨β¨β¨ππππβ¨β¨β¨β¨ππ"
)
.unwrap(),
"γγγ°γ",
);
}
#[test]
fn test_embedded_null_byte() {
assert_eq!(
encode_string(&"\0"),
"β€οΈππ",
);
assert_eq!(
decode_string(&"β€οΈππ")
.unwrap(),
"\0",
);
}
}