use crate::opc::{OpcError, PartFs};
use crate::xmllinq::{Dom, NodeId};
pub struct WmlDocument {
pub document_byte_array: Vec<u8>,
pub file_name: String,
part_fs: PartFs,
dom: Dom,
main_doc: Option<NodeId>,
}
impl WmlDocument {
pub fn from_bytes(bytes: &[u8]) -> Result<Self, OpcError> {
Ok(WmlDocument {
document_byte_array: bytes.to_vec(),
file_name: String::new(),
part_fs: PartFs::open(bytes)?,
dom: Dom::new(),
main_doc: None,
})
}
pub fn main_document_part_name(&self) -> String {
self.part_fs
.main_document_part()
.unwrap_or_else(|| "word/document.xml".to_string())
}
pub fn main_document(&mut self) -> Result<NodeId, OpcError> {
if let Some(id) = self.main_doc {
return Ok(id);
}
let name = self.main_document_part_name();
let xml = self
.part_fs
.part_string(&name)
.ok_or_else(|| OpcError::PartNotFound(name.clone()))?;
let doc = self.dom.parse_xdocument(&xml);
self.main_doc = Some(doc);
Ok(doc)
}
pub fn main_document_root(&mut self) -> Result<NodeId, OpcError> {
let doc = self.main_document()?;
let name = self.main_document_part_name();
self.dom
.root(doc)
.ok_or_else(|| OpcError::PartNotFound(format!("{name}: no root element")))
}
pub fn dom(&self) -> &Dom {
&self.dom
}
pub fn dom_mut(&mut self) -> &mut Dom {
&mut self.dom
}
pub fn part_fs(&self) -> &PartFs {
&self.part_fs
}
pub fn part_fs_mut(&mut self) -> &mut PartFs {
&mut self.part_fs
}
}