1use crate::types::{DocxMeta, PdfMeta};
2use roxmltree::Document;
3use std::fs::File;
4use std::io::Read;
5use std::path::Path;
6
7pub fn read_pdf_info(path: &Path) -> Option<PdfMeta> {
8 let doc = lopdf::Document::load(path).ok()?;
9 let n = doc.get_pages().len();
10 if n == 0 {
11 return None;
12 }
13 Some(PdfMeta {
14 page_count: Some(n as u32),
15 author: None,
16 title: None,
17 })
18}
19
20pub fn read_docx_core(path: &Path) -> Option<DocxMeta> {
22 let file = File::open(path).ok()?;
23 let mut archive = zip::ZipArchive::new(file).ok()?;
24 let mut zf = archive.by_name("docProps/core.xml").ok()?;
25 let mut xml = String::new();
26 zf.read_to_string(&mut xml).ok()?;
27 let doc = Document::parse(&xml).ok()?;
28
29 let mut out = DocxMeta::default();
30 for node in doc.descendants() {
31 if !node.is_element() {
32 continue;
33 }
34 let name = node.tag_name().name();
35 let text = node.text().unwrap_or("").trim();
36 if text.is_empty() {
37 continue;
38 }
39 match name {
40 "creator" => out.creator = Some(text.to_string()),
41 "lastModifiedBy" => out.last_modified_by = Some(text.to_string()),
42 "revision" => out.revision = Some(text.to_string()),
43 _ => {}
44 }
45 }
46
47 if out.creator.is_none() && out.last_modified_by.is_none() && out.revision.is_none() {
48 None
49 } else {
50 Some(out)
51 }
52}