use std::sync::{Arc, Mutex};
use docspec_core::ImageSource;
use crate::content_types::ContentTypes;
use crate::numbering::{ListLookupResult, MinimalNumbering};
use crate::package::ReadSeek;
use crate::rels::{HyperlinkMap, ImageMap};
use crate::styles::{StyleClassification, StyleList};
pub struct DocxData {
pub style_list: StyleList,
pub hyperlink_map: HyperlinkMap,
pub numbering: MinimalNumbering,
pub image_map: ImageMap,
}
pub(crate) struct PackageContext {
style_list: StyleList,
hyperlink_map: HyperlinkMap,
numbering: MinimalNumbering,
image_map: ImageMap,
archive: Arc<Mutex<zip::ZipArchive<Box<dyn ReadSeek + 'static>>>>,
content_types: Arc<ContentTypes>,
}
impl core::fmt::Debug for PackageContext {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("PackageContext")
.field("hyperlink_map", &self.hyperlink_map)
.finish_non_exhaustive()
}
}
impl PackageContext {
pub(crate) fn new(
data: DocxData,
archive: Arc<Mutex<zip::ZipArchive<Box<dyn ReadSeek + 'static>>>>,
content_types: Arc<ContentTypes>,
) -> Self {
let DocxData {
style_list,
hyperlink_map,
numbering,
image_map,
} = data;
Self {
style_list,
hyperlink_map,
numbering,
image_map,
archive,
content_types,
}
}
pub(crate) fn classify_style(&self, id: &str) -> Option<StyleClassification> {
self.style_list.classify(id)
}
pub(crate) fn resolve_numbering(&self, num_id: u32, ilvl: u32) -> ListLookupResult {
self.numbering.resolve(num_id, ilvl)
}
pub(crate) fn hyperlink_target(&self, rid: &str) -> Option<String> {
self.hyperlink_map.get(rid).cloned()
}
pub(crate) fn image_source_for_rid(&self, rid: &str) -> ImageSource {
let asset_id = match self.image_map.get(rid) {
Some(rel) if rel.is_external => {
return ImageSource::Uri {
uri: rel.target.clone(),
}
}
Some(rel) => format!("zip://{}", rel.target),
None => rid.to_string(),
};
ImageSource::Asset(Arc::new(crate::asset_provider::DocxAssetHandle::new(
Arc::clone(&self.archive),
Arc::clone(&self.content_types),
asset_id,
)))
}
}