use crate::ooxml::docx::document::Document;
use crate::ooxml::docx::parts::DocumentPart;
use crate::ooxml::error::{OoxmlError, Result};
use crate::ooxml::opc::constants::content_type as ct;
use crate::ooxml::opc::OpcPackage;
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 document part: {}", e)))?;
let content_type = main_part.content_type();
if content_type != ct::WML_DOCUMENT_MAIN {
return Err(OoxmlError::InvalidContentType {
expected: ct::WML_DOCUMENT_MAIN.to_string(),
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 document part: {}", e)))?;
let content_type = main_part.content_type();
if content_type != ct::WML_DOCUMENT_MAIN {
return Err(OoxmlError::InvalidContentType {
expected: ct::WML_DOCUMENT_MAIN.to_string(),
got: content_type.to_string(),
});
}
Ok(Self { opc })
}
pub fn document(&self) -> Result<Document<'_>> {
let main_part = self
.opc
.main_document_part()
.map_err(|e| OoxmlError::PartNotFound(format!("main document part: {}", e)))?;
let doc_part = DocumentPart::from_part(main_part)?;
Ok(Document::new(doc_part))
}
#[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.docx");
assert!(result.is_ok());
}
}