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, tree: &Dictionary, named_destinations: &mut IndexMap<Vec<u8>, Destination>,
35    ) -> Result<()> {
36        if let Ok(kids) = tree.get(b"Kids") {
37            for kid in kids.as_array()? {
38                if let Ok(kid) = kid.as_reference().and_then(move |id| self.get_dictionary(id)) {
39                    self.get_named_destinations(kid, named_destinations)?;
40                }
41            }
42        }
43        if let Ok(names) = tree.get(b"Names") {
44            let mut names = names.as_array()?.iter();
45            loop {
46                let key = names.next();
47                if key.is_none() {
48                    break;
49                }
50                let val = names.next();
51                if val.is_none() {
52                    break;
53                }
54                if let Ok(obj_ref) = val.unwrap().as_reference() {
55                    if let Ok(dict) = self.get_dictionary(obj_ref) {
56                        let val = dict.get(b"D").as_ref().unwrap().as_array()?;
57                        let dest = Destination::new(key.unwrap().clone(), val[0].clone(), val[1].clone());
58                        named_destinations.insert(key.unwrap().as_str().unwrap().to_vec(), dest);
59                    } else if let Ok(Object::Array(val)) = self.get_object(obj_ref) {
60                        let dest = Destination::new(key.unwrap().clone(), val[0].clone(), val[1].clone());
61                        named_destinations.insert(key.unwrap().as_str().unwrap().to_vec(), dest);
62                    }
63                } else if let Ok(dict) = val.unwrap().as_dict() {
64                    let val = dict.get(b"D").as_ref().unwrap().as_array()?;
65                    let dest = Destination::new(key.unwrap().clone(), val[0].clone(), val[1].clone());
66                    named_destinations.insert(key.unwrap().as_str().unwrap().to_vec(), dest);
67                } else {
68                    // TODO: Log error: Unpexpected node type
69                }
70            }
71        }
72        Ok(())
73    }
74}