Skip to main content

pdfluent_lopdf/
destinations.rs

1use super::{Dictionary, Document, Object, Result};
2use indexmap::IndexMap;
3#[derive(Debug, Clone)]
4pub struct Destination(Dictionary);
5
6impl Destination {
7    pub fn new(title: Object, page: Object, typ: Object) -> Self {
8        let mut dict = Dictionary::new();
9        dict.set(b"Title", title);
10        dict.set(b"Page", page);
11        dict.set(b"Type", typ);
12        Destination(dict)
13    }
14
15    pub fn set<K, V>(&mut self, key: K, value: V)
16    where
17        K: Into<Vec<u8>>,
18        V: Into<Object>,
19    {
20        self.0.set(key, value);
21    }
22
23    pub fn title(&self) -> Result<&Object> {
24        self.0.get(b"Title")
25    }
26
27    pub fn page(&self) -> Result<&Object> {
28        self.0.get(b"Page")
29    }
30}
31
32impl Document {
33    pub fn get_named_destinations(
34        &self,
35        tree: &Dictionary,
36        named_destinations: &mut IndexMap<Vec<u8>, Destination>,
37    ) -> Result<()> {
38        if let Ok(kids) = tree.get(b"Kids") {
39            for kid in kids.as_array()? {
40                if let Ok(kid) = kid
41                    .as_reference()
42                    .and_then(move |id| self.get_dictionary(id))
43                {
44                    self.get_named_destinations(kid, named_destinations)?;
45                }
46            }
47        }
48        if let Ok(names) = tree.get(b"Names") {
49            let mut names = names.as_array()?.iter();
50            loop {
51                let key = names.next();
52                if key.is_none() {
53                    break;
54                }
55                let val = names.next();
56                if val.is_none() {
57                    break;
58                }
59                if let Ok(obj_ref) = val.unwrap().as_reference() {
60                    if let Ok(dict) = self.get_dictionary(obj_ref) {
61                        let val = dict.get(b"D").as_ref().unwrap().as_array()?;
62                        let dest =
63                            Destination::new(key.unwrap().clone(), val[0].clone(), val[1].clone());
64                        named_destinations.insert(key.unwrap().as_str().unwrap().to_vec(), dest);
65                    } else if let Ok(Object::Array(val)) = self.get_object(obj_ref) {
66                        let dest =
67                            Destination::new(key.unwrap().clone(), val[0].clone(), val[1].clone());
68                        named_destinations.insert(key.unwrap().as_str().unwrap().to_vec(), dest);
69                    }
70                } else if let Ok(dict) = val.unwrap().as_dict() {
71                    let val = dict.get(b"D").as_ref().unwrap().as_array()?;
72                    let dest =
73                        Destination::new(key.unwrap().clone(), val[0].clone(), val[1].clone());
74                    named_destinations.insert(key.unwrap().as_str().unwrap().to_vec(), dest);
75                } else {
76                    // TODO: Log error: Unpexpected node type
77                }
78            }
79        }
80        Ok(())
81    }
82}