use crate::xref::XRef;
use super::object::{Dictionary, Object};
use std::{fmt::Display, rc::Rc};
#[derive(Debug, PartialEq)]
pub struct Info {
title: Option<String>,
author: Option<String>,
creator: Option<String>,
producer: Option<String>,
creation_date: Option<String>, mod_date: Option<String>, }
impl Display for Info {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Title: {:?}\nAuthor: {:?}\nCreator: {:?}\nProducer: {:?}\nCreationDate: {:?}\nModDate: {:?}",
self.title, self.author, self.creator, self.producer, self.creation_date, self.mod_date)
}
}
impl Info {
pub fn new(bytes: &[u8], curr_idx: usize, xref: Rc<XRef>) -> Self {
match Object::new(bytes, curr_idx, xref) {
Object::Dictionary(dict) => Self::from(dict),
_ => panic!("Trailer should be a dictionary"),
}
}
}
impl From<Dictionary<'_>> for Info {
fn from(value: Dictionary) -> Self {
Info {
title: match value.get("Title") {
Some(Object::String(s)) => Some(String::from(s)),
None => None,
_ => panic!("Title should be a string"),
},
author: match value.get("Author") {
Some(Object::String(s)) => Some(String::from(s)),
None => None,
_ => panic!("Author should be a string"),
},
creator: match value.get("Creator") {
Some(Object::String(s)) => Some(String::from(s)),
Some(Object::HexString(s)) => Some(match std::str::from_utf8(s) {
Ok(s) => String::from(s),
Err(..) => String::new(), }),
None => None,
_ => panic!("Creator should be a string"),
},
producer: match value.get("Producer") {
Some(Object::String(s)) => Some(String::from(s)),
Some(Object::HexString(s)) => Some(match std::str::from_utf8(s) {
Ok(s) => String::from(s),
Err(..) => String::new(), }),
None => None,
_ => panic!("Producer should be a string"),
},
creation_date: match value.get("CreationDate") {
Some(Object::String(s)) => Some(String::from(s)),
None => None,
_ => panic!("CreationDate should be a string"),
},
mod_date: match value.get("ModDate") {
Some(Object::String(s)) => Some(String::from(s)),
None => None,
_ => panic!("ModDate should be a string"),
},
}
}
}
#[cfg(test)]
mod tests {
use crate::xref::XRefTable;
use super::*;
#[test]
fn test_info_dict_1() {
let bytes = b"1 0 obj\n<< /Title (sample) /Author (Philip Hutchison) /Creator (Pages) /Producer (Mac OS X 10.5.4 Quartz PDFContext)\n/CreationDate (D:20080701052447Z00'00') /ModDate (D:20080701052447Z00'00')\n>>\nendobj";
let xref = Rc::new(XRef::XRefTable(XRefTable::default()));
let info = Info::new(bytes.as_slice(), 0, xref);
assert_eq!(
info,
Info {
title: Some(String::from("sample")),
author: Some(String::from("Philip Hutchison")),
creator: Some(String::from("Pages")),
producer: Some(String::from("Mac OS X 10.5.4 Quartz PDFContext")),
creation_date: Some(String::from("D:20080701052447Z00'00'")),
mod_date: Some(String::from("D:20080701052447Z00'00'"))
}
);
}
}