use crate::ooxml::error::{OoxmlError, Result};
use crate::ooxml::opc::constants::content_type as ct;
use crate::ooxml::opc::OpcPackage;
use crate::ooxml::pptx::presentation::Presentation;
use crate::ooxml::pptx::parts::PresentationPart;
use std::io::{Read, Seek};
use std::path::Path;
pub struct Package {
opc: OpcPackage,
}
impl Package {
pub fn open<P: AsRef<Path>>(path: P) -> Result<Self> {
let opc = OpcPackage::open(path)?;
let main_part = opc
.main_document_part()
.map_err(|e| OoxmlError::PartNotFound(format!("main presentation part: {}", e)))?;
let content_type = main_part.content_type();
if content_type != ct::PML_PRESENTATION_MAIN && content_type != ct::PML_PRES_MACRO_MAIN {
return Err(OoxmlError::InvalidContentType {
expected: format!(
"{} or {}",
ct::PML_PRESENTATION_MAIN,
ct::PML_PRES_MACRO_MAIN
),
got: content_type.to_string(),
});
}
Ok(Self { opc })
}
pub fn from_reader<R: Read + Seek>(reader: R) -> Result<Self> {
let opc = OpcPackage::from_reader(reader)?;
let main_part = opc
.main_document_part()
.map_err(|e| OoxmlError::PartNotFound(format!("main presentation part: {}", e)))?;
let content_type = main_part.content_type();
if content_type != ct::PML_PRESENTATION_MAIN && content_type != ct::PML_PRES_MACRO_MAIN {
return Err(OoxmlError::InvalidContentType {
expected: format!(
"{} or {}",
ct::PML_PRESENTATION_MAIN,
ct::PML_PRES_MACRO_MAIN
),
got: content_type.to_string(),
});
}
Ok(Self { opc })
}
pub fn presentation(&self) -> Result<Presentation<'_>> {
let main_part = self
.opc
.main_document_part()
.map_err(|e| OoxmlError::PartNotFound(format!("main presentation part: {}", e)))?;
let pres_part = PresentationPart::from_part(main_part)?;
Ok(Presentation::new(pres_part, &self.opc))
}
#[inline]
pub fn opc_package(&self) -> &OpcPackage {
&self.opc
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
#[ignore] fn test_open_package() {
let result = Package::open("test.pptx");
assert!(result.is_ok());
}
}