Skip to main content

rust_pdf_box/pd/
info.rs

1use crate::cos::object::{COSDictionary, COSString};
2use chrono::{DateTime, Utc};
3
4/// Document metadata (/Info dictionary).
5#[derive(Debug, Clone, Default)]
6pub struct PDDocumentInformation {
7    pub dict: COSDictionary,
8}
9
10impl PDDocumentInformation {
11    pub fn new() -> Self {
12        let mut info = Self {
13            dict: COSDictionary::new(),
14        };
15        info.set_producer("rust-pdf-box (Techwasti Infotech)");
16        let now = Utc::now();
17        info.set_creation_date(now);
18        info.set_modification_date(now);
19        info
20    }
21
22    pub fn from_dict(dict: COSDictionary) -> Self {
23        Self { dict }
24    }
25
26    pub fn title(&self) -> Option<String> {
27        self.dict.get_string("Title").map(|s| s.to_string_lossy())
28    }
29
30    pub fn set_title(&mut self, title: impl Into<String>) {
31        self.dict
32            .set("Title", COSString::literal(title.into().into_bytes()));
33    }
34
35    pub fn author(&self) -> Option<String> {
36        self.dict.get_string("Author").map(|s| s.to_string_lossy())
37    }
38
39    pub fn set_author(&mut self, author: impl Into<String>) {
40        self.dict
41            .set("Author", COSString::literal(author.into().into_bytes()));
42    }
43
44    pub fn subject(&self) -> Option<String> {
45        self.dict.get_string("Subject").map(|s| s.to_string_lossy())
46    }
47
48    pub fn set_subject(&mut self, subject: impl Into<String>) {
49        self.dict
50            .set("Subject", COSString::literal(subject.into().into_bytes()));
51    }
52
53    pub fn keywords(&self) -> Option<String> {
54        self.dict
55            .get_string("Keywords")
56            .map(|s| s.to_string_lossy())
57    }
58
59    pub fn set_keywords(&mut self, keywords: impl Into<String>) {
60        self.dict
61            .set("Keywords", COSString::literal(keywords.into().into_bytes()));
62    }
63
64    pub fn creator(&self) -> Option<String> {
65        self.dict.get_string("Creator").map(|s| s.to_string_lossy())
66    }
67
68    pub fn set_creator(&mut self, creator: impl Into<String>) {
69        self.dict
70            .set("Creator", COSString::literal(creator.into().into_bytes()));
71    }
72
73    pub fn producer(&self) -> Option<String> {
74        self.dict
75            .get_string("Producer")
76            .map(|s| s.to_string_lossy())
77    }
78
79    pub fn set_producer(&mut self, producer: impl Into<String>) {
80        self.dict
81            .set("Producer", COSString::literal(producer.into().into_bytes()));
82    }
83
84    pub fn set_creation_date(&mut self, dt: DateTime<Utc>) {
85        let pdf_date = format_pdf_date(dt);
86        self.dict
87            .set("CreationDate", COSString::literal(pdf_date.into_bytes()));
88    }
89
90    pub fn set_modification_date(&mut self, dt: DateTime<Utc>) {
91        let pdf_date = format_pdf_date(dt);
92        self.dict
93            .set("ModDate", COSString::literal(pdf_date.into_bytes()));
94    }
95}
96
97pub fn format_pdf_date(dt: DateTime<Utc>) -> String {
98    // D:YYYYMMDDHHmmSSZ
99    format!("D:{}Z", dt.format("%Y%m%d%H%M%S"))
100}