1use serde::{Deserialize, Serialize};
8
9use crate::model::common::Actions;
10use crate::model::common::CtDest;
11use crate::model::page::{CtTemplatePage, Pages};
12use crate::types::{StBox, StId, StLoc, StRefId};
13
14#[derive(Debug, Clone, Deserialize, Serialize)]
16pub struct Document {
17 #[serde(rename = "CommonData")]
19 pub common_data: CommonData,
20 #[serde(rename = "Pages")]
22 pub pages: Pages,
23 #[serde(rename = "Outlines")]
25 pub outlines: Option<Outlines>,
26 #[serde(rename = "Permissions")]
28 pub permissions: Option<CtPermission>,
29 #[serde(rename = "Actions")]
31 pub actions: Option<Actions>,
32 #[serde(rename = "VPreferences")]
34 pub v_preferences: Option<VPreferences>,
35 #[serde(rename = "Bookmarks")]
37 pub bookmarks: Option<Bookmarks>,
38 #[serde(rename = "Attachments")]
40 pub attachments: Option<StLoc>,
41 #[serde(rename = "Annotations")]
43 pub annotations: Option<StLoc>,
44 #[serde(rename = "CustomTags")]
46 pub custom_tags: Option<StLoc>,
47 #[serde(rename = "Extensions")]
49 pub extensions: Option<StLoc>,
50}
51
52#[derive(Debug, Clone, Deserialize, Serialize)]
54pub struct CommonData {
55 #[serde(rename = "MaxUnitID")]
57 pub max_unit_id: StId,
58 #[serde(rename = "PageArea")]
65 pub page_area: Option<CtPageArea>,
66 #[serde(rename = "PublicRes", default)]
68 pub public_res: Vec<StLoc>,
69 #[serde(rename = "DocumentRes", default)]
71 pub document_res: Vec<StLoc>,
72 #[serde(rename = "TemplatePage", default)]
74 pub template_pages: Vec<CtTemplatePage>,
75 #[serde(rename = "DefaultCS")]
77 pub default_cs: Option<StRefId>,
78}
79
80#[derive(Debug, Clone, Deserialize, Serialize)]
84pub struct CtPageArea {
85 #[serde(rename = "PhysicalBox")]
87 pub physical_box: StBox,
88 #[serde(rename = "ApplicationBox")]
90 pub application_box: Option<StBox>,
91 #[serde(rename = "ContentBox")]
93 pub content_box: Option<StBox>,
94 #[serde(rename = "BleedBox")]
96 pub bleed_box: Option<StBox>,
97}
98
99#[derive(Debug, Clone, Default, Deserialize, Serialize)]
104pub struct CtPermission {
105 #[serde(rename = "Edit")]
107 pub edit: Option<bool>,
108 #[serde(rename = "Annot")]
110 pub annot: Option<bool>,
111 #[serde(rename = "Export")]
113 pub export: Option<bool>,
114 #[serde(rename = "Signature")]
116 pub signature: Option<bool>,
117 #[serde(rename = "Watermark")]
119 pub watermark: Option<bool>,
120 #[serde(rename = "PrintScreen")]
122 pub print_screen: Option<bool>,
123 #[serde(rename = "Print")]
125 pub print: Option<Print>,
126 #[serde(rename = "ValidPeriod")]
128 pub valid_period: Option<ValidPeriod>,
129}
130
131#[derive(Debug, Clone, Default, Deserialize, Serialize)]
133pub struct Print {
134 #[serde(rename = "@Printable")]
136 pub printable: Option<bool>,
137 #[serde(rename = "@Copies")]
139 pub copies: Option<i64>,
140}
141
142#[derive(Debug, Clone, Default, Deserialize, Serialize)]
144pub struct ValidPeriod {
145 #[serde(rename = "@StartDate")]
147 pub start_date: Option<String>,
148 #[serde(rename = "@EndDate")]
150 pub end_date: Option<String>,
151}
152
153#[derive(Debug, Clone, Default, Deserialize, Serialize)]
155pub struct VPreferences {
156 #[serde(rename = "PageMode")]
158 pub page_mode: Option<String>,
159 #[serde(rename = "PageLayout")]
161 pub page_layout: Option<String>,
162 #[serde(rename = "TabDisplay")]
164 pub tab_display: Option<String>,
165 #[serde(rename = "HideToolbar")]
167 pub hide_toolbar: Option<bool>,
168 #[serde(rename = "HideMenubar")]
170 pub hide_menubar: Option<bool>,
171 #[serde(rename = "HideWindowUI")]
173 pub hide_window_ui: Option<bool>,
174 #[serde(rename = "ZoomMode")]
176 pub zoom_mode: Option<String>,
177 #[serde(rename = "Zoom")]
179 pub zoom: Option<f64>,
180}
181
182#[derive(Debug, Clone, Default, Deserialize, Serialize)]
184pub struct Bookmarks {
185 #[serde(rename = "Bookmark", default)]
187 pub bookmarks: Vec<CtBookmark>,
188}
189
190#[derive(Debug, Clone, Default, Deserialize, Serialize)]
192pub struct CtBookmark {
193 #[serde(rename = "@Name")]
195 pub name: String,
196 #[serde(rename = "Dest")]
198 pub dest: Option<CtDest>,
199}
200
201#[derive(Debug, Clone, Default, Deserialize, Serialize)]
203pub struct Outlines {
204 #[serde(rename = "OutlineElem", default)]
206 pub outline_elems: Vec<CtOutlineElem>,
207}
208
209#[derive(Debug, Clone, Default, Deserialize, Serialize)]
211pub struct CtOutlineElem {
212 #[serde(rename = "@Title")]
214 pub title: String,
215 #[serde(rename = "@Count")]
217 pub count: Option<i64>,
218 #[serde(rename = "@Expanded")]
220 pub expanded: Option<bool>,
221 #[serde(rename = "Actions")]
223 pub actions: Option<Actions>,
224 #[serde(rename = "OutlineElem", default)]
226 pub children: Vec<CtOutlineElem>,
227}
228
229#[cfg(test)]
230mod tests {
231 use super::CommonData;
232
233 #[test]
239 fn interleaved_public_res_collects_into_vec() {
240 let xml = r#"<ofd:CommonData xmlns:ofd="http://www.ofdspec.org/2016">
241 <ofd:MaxUnitID>10</ofd:MaxUnitID>
242 <ofd:PublicRes>PublicRes.xml</ofd:PublicRes>
243 <ofd:DocumentRes>DocumentRes.xml</ofd:DocumentRes>
244 <ofd:PublicRes>PublicRes_2.xml</ofd:PublicRes>
245 </ofd:CommonData>"#;
246
247 let cd: CommonData = quick_xml::de::from_str(xml).expect("parse CommonData");
248 assert_eq!(
249 cd.public_res
250 .iter()
251 .map(|l| l.0.as_str())
252 .collect::<Vec<_>>(),
253 ["PublicRes.xml", "PublicRes_2.xml"],
254 );
255 assert_eq!(cd.document_res.len(), 1);
256 }
257}