use crate::iwa::{Error, Result};
use phf::phf_map;
use prost::Message;
include!(concat!(env!("OUT_DIR"), "/iwa_protos.rs"));
fn decode_archive_info(data: &[u8]) -> Result<Box<dyn DecodedMessage>> {
let msg = tsp::ArchiveInfo::decode(data)?;
Ok(Box::new(ArchiveInfoWrapper(msg)) as Box<dyn DecodedMessage>)
}
fn decode_message_info(data: &[u8]) -> Result<Box<dyn DecodedMessage>> {
let msg = tsp::MessageInfo::decode(data)?;
Ok(Box::new(MessageInfoWrapper(msg)) as Box<dyn DecodedMessage>)
}
fn decode_pages_document(data: &[u8]) -> Result<Box<dyn DecodedMessage>> {
let msg = tp::DocumentArchive::decode(data)?;
Ok(Box::new(PagesDocumentWrapper(msg)) as Box<dyn DecodedMessage>)
}
fn decode_numbers_document(data: &[u8]) -> Result<Box<dyn DecodedMessage>> {
let msg = tn::DocumentArchive::decode(data)?;
Ok(Box::new(NumbersDocumentWrapper(msg)) as Box<dyn DecodedMessage>)
}
fn decode_numbers_sheet(data: &[u8]) -> Result<Box<dyn DecodedMessage>> {
let msg = tn::SheetArchive::decode(data)?;
Ok(Box::new(NumbersSheetWrapper(msg)) as Box<dyn DecodedMessage>)
}
fn decode_keynote_show(data: &[u8]) -> Result<Box<dyn DecodedMessage>> {
let msg = kn::ShowArchive::decode(data)?;
Ok(Box::new(KeynoteShowWrapper(msg)) as Box<dyn DecodedMessage>)
}
fn decode_keynote_slide(data: &[u8]) -> Result<Box<dyn DecodedMessage>> {
let msg = kn::SlideArchive::decode(data)?;
Ok(Box::new(KeynoteSlideWrapper(msg)) as Box<dyn DecodedMessage>)
}
fn decode_storage_archive(data: &[u8]) -> Result<Box<dyn DecodedMessage>> {
let msg = tswp::StorageArchive::decode(data)?;
Ok(Box::new(StorageArchiveWrapper(msg)) as Box<dyn DecodedMessage>)
}
fn decode_table_model(data: &[u8]) -> Result<Box<dyn DecodedMessage>> {
let msg = tst::TableModelArchive::decode(data)?;
Ok(Box::new(TableModelWrapper(msg)) as Box<dyn DecodedMessage>)
}
fn decode_table_data_list(data: &[u8]) -> Result<Box<dyn DecodedMessage>> {
let msg = tst::TableDataList::decode(data)?;
Ok(Box::new(TableDataListWrapper(msg)) as Box<dyn DecodedMessage>)
}
fn decode_shape_archive(data: &[u8]) -> Result<Box<dyn DecodedMessage>> {
let msg = tsd::ShapeArchive::decode(data)?;
Ok(Box::new(ShapeArchiveWrapper(msg)) as Box<dyn DecodedMessage>)
}
fn decode_drawable_archive(data: &[u8]) -> Result<Box<dyn DecodedMessage>> {
let msg = tsd::DrawableArchive::decode(data)?;
Ok(Box::new(DrawableArchiveWrapper(msg)) as Box<dyn DecodedMessage>)
}
fn decode_chart_archive(data: &[u8]) -> Result<Box<dyn DecodedMessage>> {
let msg = tsch::ChartArchive::decode(data)?;
Ok(Box::new(ChartArchiveWrapper(msg)) as Box<dyn DecodedMessage>)
}
type DecoderMap = phf::Map<u32, fn(&[u8]) -> Result<Box<dyn DecodedMessage>>>;
static DECODERS: DecoderMap = phf_map! {
1u32 => decode_archive_info,
2u32 => decode_message_info,
100u32 => decode_table_model,
101u32 => decode_table_data_list,
500u32 => decode_shape_archive,
501u32 => decode_drawable_archive,
600u32 => decode_chart_archive,
200u32 => decode_storage_archive,
201u32 => decode_storage_archive,
202u32 => decode_storage_archive,
203u32 => decode_storage_archive,
204u32 => decode_storage_archive,
205u32 => decode_storage_archive,
2001u32 => decode_storage_archive,
2002u32 => decode_storage_archive,
2003u32 => decode_storage_archive,
2004u32 => decode_storage_archive,
2005u32 => decode_storage_archive,
2011u32 => decode_storage_archive,
2012u32 => decode_storage_archive,
2022u32 => decode_storage_archive,
1001u32 => decode_pages_document,
1002u32 => decode_numbers_document,
1003u32 => decode_numbers_sheet,
1101u32 => decode_keynote_show,
1102u32 => decode_keynote_slide,
};
pub fn decode(message_type: u32, data: &[u8]) -> Result<Box<dyn DecodedMessage>> {
if let Some(decoder) = DECODERS.get(&message_type) {
decoder(data)
} else {
Err(Error::UnsupportedMessageType(message_type))
}
}
pub trait DecodedMessage: std::fmt::Debug {
fn message_type(&self) -> u32;
fn extract_text(&self) -> Vec<String> {
Vec::new()
}
}
#[derive(Debug)]
pub struct ArchiveInfoWrapper(pub tsp::ArchiveInfo);
impl DecodedMessage for ArchiveInfoWrapper {
fn message_type(&self) -> u32 { 1 }
fn extract_text(&self) -> Vec<String> {
Vec::new() }
}
#[derive(Debug)]
pub struct MessageInfoWrapper(pub tsp::MessageInfo);
impl DecodedMessage for MessageInfoWrapper {
fn message_type(&self) -> u32 { 2 }
fn extract_text(&self) -> Vec<String> {
Vec::new() }
}
#[derive(Debug)]
pub struct StorageArchiveWrapper(pub tswp::StorageArchive);
impl DecodedMessage for StorageArchiveWrapper {
fn message_type(&self) -> u32 { 200 }
fn extract_text(&self) -> Vec<String> {
self.0.text.clone()
}
}
#[derive(Debug)]
pub struct PagesDocumentWrapper(pub tp::DocumentArchive);
impl DecodedMessage for PagesDocumentWrapper {
fn message_type(&self) -> u32 { 1001 }
fn extract_text(&self) -> Vec<String> {
Vec::new() }
}
#[derive(Debug)]
pub struct NumbersDocumentWrapper(pub tn::DocumentArchive);
impl DecodedMessage for NumbersDocumentWrapper {
fn message_type(&self) -> u32 { 1002 }
fn extract_text(&self) -> Vec<String> {
Vec::new() }
}
#[derive(Debug)]
pub struct NumbersSheetWrapper(pub tn::SheetArchive);
impl DecodedMessage for NumbersSheetWrapper {
fn message_type(&self) -> u32 { 1003 }
fn extract_text(&self) -> Vec<String> {
if !self.0.name.is_empty() {
vec![self.0.name.clone()]
} else {
Vec::new()
}
}
}
#[derive(Debug)]
pub struct KeynoteShowWrapper(pub kn::ShowArchive);
impl DecodedMessage for KeynoteShowWrapper {
fn message_type(&self) -> u32 { 1101 }
fn extract_text(&self) -> Vec<String> {
Vec::new()
}
}
#[derive(Debug)]
pub struct KeynoteSlideWrapper(pub kn::SlideArchive);
impl DecodedMessage for KeynoteSlideWrapper {
fn message_type(&self) -> u32 { 1102 }
fn extract_text(&self) -> Vec<String> {
let mut text = Vec::new();
if let Some(ref name) = self.0.name
&& !name.is_empty() {
text.push(name.clone());
}
text
}
}
#[derive(Debug)]
pub struct TableModelWrapper(pub tst::TableModelArchive);
impl DecodedMessage for TableModelWrapper {
fn message_type(&self) -> u32 { 100 }
fn extract_text(&self) -> Vec<String> {
let mut text = Vec::new();
if !self.0.table_name.is_empty() {
text.push(self.0.table_name.clone());
}
text
}
}
#[derive(Debug)]
pub struct TableDataListWrapper(pub tst::TableDataList);
impl DecodedMessage for TableDataListWrapper {
fn message_type(&self) -> u32 { 101 }
fn extract_text(&self) -> Vec<String> {
Vec::new()
}
}
#[derive(Debug)]
pub struct ShapeArchiveWrapper(pub tsd::ShapeArchive);
impl DecodedMessage for ShapeArchiveWrapper {
fn message_type(&self) -> u32 { 500 }
fn extract_text(&self) -> Vec<String> {
Vec::new()
}
}
#[derive(Debug)]
pub struct DrawableArchiveWrapper(pub tsd::DrawableArchive);
impl DecodedMessage for DrawableArchiveWrapper {
fn message_type(&self) -> u32 { 501 }
fn extract_text(&self) -> Vec<String> {
Vec::new()
}
}
#[derive(Debug)]
pub struct ChartArchiveWrapper(pub tsch::ChartArchive);
impl DecodedMessage for ChartArchiveWrapper {
fn message_type(&self) -> u32 { 600 }
fn extract_text(&self) -> Vec<String> {
Vec::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_message_decoder_creation() {
assert!(DECODERS.contains_key(&1)); assert!(DECODERS.contains_key(&2)); assert!(DECODERS.contains_key(&100)); assert!(DECODERS.contains_key(&200)); assert!(DECODERS.contains_key(&201)); assert!(DECODERS.contains_key(&202)); assert!(DECODERS.contains_key(&2022)); assert!(DECODERS.contains_key(&1001)); assert!(DECODERS.contains_key(&1002)); assert!(DECODERS.contains_key(&1003)); assert!(DECODERS.contains_key(&1101)); assert!(DECODERS.contains_key(&1102)); }
#[test]
fn test_unsupported_message_type() {
let result = decode(999, &[]);
assert!(matches!(result, Err(Error::UnsupportedMessageType(999))));
}
#[test]
fn test_decoder_performance() {
let message_types = [1, 2, 100, 200, 201, 202, 1001, 1002, 1101];
let dummy_data = vec![0u8; 10];
for &msg_type in &message_types {
let result = decode(msg_type, &dummy_data);
assert!(result.is_err());
}
}
}