use plist::Value;
use std::io::Cursor;
use crate::{
error::plist::PlistParseError,
util::plist::{
extract_array_key, extract_bytes_key, extract_dict_idx, extract_dictionary,
extract_string_key, parse_ns_keyed_archiver, plist_as_dictionary,
},
};
#[derive(Debug, PartialEq, Eq)]
pub struct Translation {
pub translated_text: String,
pub translation_lang: String,
pub source_lang: String,
}
impl Translation {
pub fn from_payload(plist: &Value) -> Result<Self, PlistParseError> {
let translation_data = extract_bytes_key(plist_as_dictionary(plist)?, "tmp")?;
let inner_plist = parse_ns_keyed_archiver(
&Value::from_reader(Cursor::new(translation_data))
.map_err(|_| PlistParseError::NoPayload)?,
)?;
let translation_data = extract_dict_idx(
extract_array_key(
extract_dictionary(plist_as_dictionary(&inner_plist)?, "0")?,
"0",
)?,
0,
)?;
Ok(Self {
translated_text: extract_string_key(
extract_dictionary(translation_data, "translatedText")?,
"NSString",
)?
.to_string(),
translation_lang: extract_string_key(translation_data, "translationLanguage")?
.to_string(),
source_lang: extract_string_key(translation_data, "sourceLanguage")?.to_string(),
})
}
}
#[cfg(test)]
mod tests {
use std::{env::current_dir, fs::File};
use plist::Value;
use crate::message_types::translation::Translation;
#[test]
fn test_parse_translation() {
let plist_path = current_dir()
.unwrap()
.as_path()
.join("test_data/app_message/Translation.plist");
let plist_data = File::open(plist_path).unwrap();
let plist = Value::from_reader(plist_data).unwrap();
let translation = Translation::from_payload(&plist).unwrap();
println!("{:#?}", translation);
assert_eq!(
translation.translated_text,
"Oh, il a traduit ce que j'ai envoyé !"
);
assert_eq!(translation.source_lang, "en_US");
assert_eq!(translation.translation_lang, "fr_FR");
}
#[test]
fn test_parse_translation_received() {
let plist_path = current_dir()
.unwrap()
.as_path()
.join("test_data/app_message/TranslationReceived.plist");
let plist_data = File::open(plist_path).unwrap();
let plist = Value::from_reader(plist_data).unwrap();
let translation = Translation::from_payload(&plist).unwrap();
println!("{:#?}", translation);
assert_eq!(translation.translated_text, "I want chicken");
assert_eq!(translation.source_lang, "fr_FR");
assert_eq!(translation.translation_lang, "en_US");
}
}