1use crate::types::{PdfName, PdfValue};
2use indexmap::IndexMap;
3use std::fmt;
4
5#[derive(Debug, Clone, PartialEq, Default)]
6pub struct PdfArray {
7 elements: Vec<PdfValue>,
8}
9
10impl PdfArray {
11 pub fn new() -> Self {
12 PdfArray {
13 elements: Vec::new(),
14 }
15 }
16
17 pub fn with_capacity(capacity: usize) -> Self {
18 PdfArray {
19 elements: Vec::with_capacity(capacity),
20 }
21 }
22
23 pub fn push(&mut self, value: PdfValue) {
24 self.elements.push(value);
25 }
26
27 pub fn get(&self, index: usize) -> Option<&PdfValue> {
28 self.elements.get(index)
29 }
30
31 pub fn get_mut(&mut self, index: usize) -> Option<&mut PdfValue> {
32 self.elements.get_mut(index)
33 }
34
35 pub fn len(&self) -> usize {
36 self.elements.len()
37 }
38
39 pub fn is_empty(&self) -> bool {
40 self.elements.is_empty()
41 }
42
43 pub fn iter(&self) -> impl Iterator<Item = &PdfValue> {
44 self.elements.iter()
45 }
46
47 pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut PdfValue> {
48 self.elements.iter_mut()
49 }
50
51 pub fn into_vec(self) -> Vec<PdfValue> {
52 self.elements
53 }
54
55 pub fn as_slice(&self) -> &[PdfValue] {
56 &self.elements
57 }
58
59 pub fn truncate(&mut self, len: usize) {
60 self.elements.truncate(len);
61 }
62}
63
64impl std::ops::Index<usize> for PdfArray {
65 type Output = PdfValue;
66
67 fn index(&self, index: usize) -> &Self::Output {
68 &self.elements[index]
69 }
70}
71
72impl<'a> IntoIterator for &'a PdfArray {
73 type Item = &'a PdfValue;
74 type IntoIter = std::slice::Iter<'a, PdfValue>;
75
76 fn into_iter(self) -> Self::IntoIter {
77 self.elements.iter()
78 }
79}
80
81impl fmt::Display for PdfArray {
82 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
83 write!(f, "[")?;
84 for (i, elem) in self.elements.iter().enumerate() {
85 if i > 0 {
86 write!(f, " ")?;
87 }
88 write!(f, "{}", elem)?;
89 }
90 write!(f, "]")
91 }
92}
93
94impl From<Vec<PdfValue>> for PdfArray {
95 fn from(elements: Vec<PdfValue>) -> Self {
96 PdfArray { elements }
97 }
98}
99
100impl IntoIterator for PdfArray {
101 type Item = PdfValue;
102 type IntoIter = std::vec::IntoIter<PdfValue>;
103
104 fn into_iter(self) -> Self::IntoIter {
105 self.elements.into_iter()
106 }
107}
108
109#[derive(Debug, Clone, PartialEq, Default)]
110pub struct PdfDictionary {
111 entries: IndexMap<PdfName, PdfValue>,
112}
113
114impl PdfDictionary {
115 pub fn new() -> Self {
116 PdfDictionary {
117 entries: IndexMap::new(),
118 }
119 }
120
121 pub fn with_capacity(capacity: usize) -> Self {
122 PdfDictionary {
123 entries: IndexMap::with_capacity(capacity),
124 }
125 }
126
127 pub fn insert(&mut self, key: impl Into<PdfName>, value: PdfValue) -> Option<PdfValue> {
128 self.entries.insert(key.into(), value)
129 }
130
131 pub fn get(&self, key: &str) -> Option<&PdfValue> {
132 self.entries.get(&PdfName::new(key))
133 }
134
135 pub fn get_mut(&mut self, key: &str) -> Option<&mut PdfValue> {
136 self.entries.get_mut(&PdfName::new(key))
137 }
138
139 pub fn get_name(&self, key: &PdfName) -> Option<&PdfValue> {
140 self.entries.get(key)
141 }
142
143 pub fn get_name_mut(&mut self, key: &PdfName) -> Option<&mut PdfValue> {
144 self.entries.get_mut(key)
145 }
146
147 pub fn remove(&mut self, key: &str) -> Option<PdfValue> {
148 self.entries.swap_remove(&PdfName::new(key))
149 }
150
151 pub fn contains_key(&self, key: &str) -> bool {
152 self.entries.contains_key(&PdfName::new(key))
153 }
154
155 pub fn len(&self) -> usize {
156 self.entries.len()
157 }
158
159 pub fn is_empty(&self) -> bool {
160 self.entries.is_empty()
161 }
162
163 pub fn iter(&self) -> impl Iterator<Item = (&PdfName, &PdfValue)> {
164 self.entries.iter()
165 }
166
167 pub fn iter_mut(&mut self) -> impl Iterator<Item = (&PdfName, &mut PdfValue)> {
168 self.entries.iter_mut()
169 }
170
171 pub fn keys(&self) -> impl Iterator<Item = &PdfName> {
172 self.entries.keys()
173 }
174
175 pub fn values(&self) -> impl Iterator<Item = &PdfValue> {
176 self.entries.values()
177 }
178
179 pub fn get_type(&self) -> Option<&PdfName> {
180 self.get("Type").and_then(|v| v.as_name())
181 }
182
183 pub fn get_subtype(&self) -> Option<&PdfName> {
184 self.get("Subtype").and_then(|v| v.as_name())
185 }
186
187 pub fn into_map(self) -> IndexMap<PdfName, PdfValue> {
188 self.entries
189 }
190
191 pub fn entry(
192 &mut self,
193 key: impl Into<PdfName>,
194 ) -> indexmap::map::Entry<'_, PdfName, PdfValue> {
195 self.entries.entry(key.into())
196 }
197}
198
199impl<'a> IntoIterator for &'a PdfDictionary {
200 type Item = (&'a PdfName, &'a PdfValue);
201 type IntoIter = indexmap::map::Iter<'a, PdfName, PdfValue>;
202
203 fn into_iter(self) -> Self::IntoIter {
204 self.entries.iter()
205 }
206}
207
208impl fmt::Display for PdfDictionary {
209 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
210 write!(f, "<<")?;
211 for (i, (key, value)) in self.entries.iter().enumerate() {
212 if i > 0 {
213 write!(f, " ")?;
214 }
215 write!(f, "{} {}", key, value)?;
216 }
217 write!(f, ">>")
218 }
219}
220
221impl From<IndexMap<PdfName, PdfValue>> for PdfDictionary {
222 fn from(entries: IndexMap<PdfName, PdfValue>) -> Self {
223 PdfDictionary { entries }
224 }
225}
226
227impl IntoIterator for PdfDictionary {
228 type Item = (PdfName, PdfValue);
229 type IntoIter = indexmap::map::IntoIter<PdfName, PdfValue>;
230
231 fn into_iter(self) -> Self::IntoIter {
232 self.entries.into_iter()
233 }
234}