1use serde::{Deserialize, Serialize};
6
7use crate::namespaces;
8
9#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
11#[serde(rename = "wsDr")]
12pub struct WsDr {
13 #[serde(rename = "@xmlns:xdr")]
14 pub xmlns_xdr: String,
15
16 #[serde(rename = "@xmlns:a")]
17 pub xmlns_a: String,
18
19 #[serde(rename = "@xmlns:r")]
20 pub xmlns_r: String,
21
22 #[serde(rename = "xdr:twoCellAnchor", default)]
23 pub two_cell_anchors: Vec<TwoCellAnchor>,
24
25 #[serde(rename = "xdr:oneCellAnchor", default)]
26 pub one_cell_anchors: Vec<OneCellAnchor>,
27}
28
29impl Default for WsDr {
30 fn default() -> Self {
31 Self {
32 xmlns_xdr: namespaces::DRAWING_ML_SPREADSHEET.to_string(),
33 xmlns_a: namespaces::DRAWING_ML.to_string(),
34 xmlns_r: namespaces::RELATIONSHIPS.to_string(),
35 two_cell_anchors: vec![],
36 one_cell_anchors: vec![],
37 }
38 }
39}
40
41#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
43pub struct TwoCellAnchor {
44 #[serde(rename = "xdr:from")]
45 pub from: MarkerType,
46
47 #[serde(rename = "xdr:to")]
48 pub to: MarkerType,
49
50 #[serde(rename = "xdr:graphicFrame", skip_serializing_if = "Option::is_none")]
51 pub graphic_frame: Option<GraphicFrame>,
52
53 #[serde(rename = "xdr:pic", skip_serializing_if = "Option::is_none")]
54 pub pic: Option<Picture>,
55
56 #[serde(rename = "xdr:sp", skip_serializing_if = "Option::is_none")]
57 pub shape: Option<Shape>,
58
59 #[serde(rename = "xdr:clientData")]
60 pub client_data: ClientData,
61}
62
63#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
65pub struct OneCellAnchor {
66 #[serde(rename = "xdr:from")]
67 pub from: MarkerType,
68
69 #[serde(rename = "xdr:ext")]
70 pub ext: Extent,
71
72 #[serde(rename = "xdr:pic", skip_serializing_if = "Option::is_none")]
73 pub pic: Option<Picture>,
74
75 #[serde(rename = "xdr:clientData")]
76 pub client_data: ClientData,
77}
78
79#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
81pub struct MarkerType {
82 #[serde(rename = "xdr:col")]
83 pub col: u32,
84
85 #[serde(rename = "xdr:colOff")]
86 pub col_off: u64,
87
88 #[serde(rename = "xdr:row")]
89 pub row: u32,
90
91 #[serde(rename = "xdr:rowOff")]
92 pub row_off: u64,
93}
94
95#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
97pub struct Extent {
98 #[serde(rename = "@cx")]
99 pub cx: u64,
100
101 #[serde(rename = "@cy")]
102 pub cy: u64,
103}
104
105#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
107pub struct GraphicFrame {
108 #[serde(rename = "xdr:nvGraphicFramePr")]
109 pub nv_graphic_frame_pr: NvGraphicFramePr,
110
111 #[serde(rename = "xdr:xfrm")]
112 pub xfrm: Xfrm,
113
114 #[serde(rename = "a:graphic")]
115 pub graphic: Graphic,
116}
117
118#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
120pub struct NvGraphicFramePr {
121 #[serde(rename = "xdr:cNvPr")]
122 pub c_nv_pr: CNvPr,
123
124 #[serde(rename = "xdr:cNvGraphicFramePr")]
125 pub c_nv_graphic_frame_pr: CNvGraphicFramePr,
126}
127
128#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
130pub struct CNvPr {
131 #[serde(rename = "@id")]
132 pub id: u32,
133
134 #[serde(rename = "@name")]
135 pub name: String,
136}
137
138#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
140pub struct CNvGraphicFramePr {}
141
142#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
144pub struct Xfrm {
145 #[serde(rename = "a:off")]
146 pub off: Offset,
147
148 #[serde(rename = "a:ext")]
149 pub ext: AExt,
150}
151
152#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
154pub struct Offset {
155 #[serde(rename = "@x")]
156 pub x: i64,
157
158 #[serde(rename = "@y")]
159 pub y: i64,
160}
161
162#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
164pub struct AExt {
165 #[serde(rename = "@cx")]
166 pub cx: u64,
167
168 #[serde(rename = "@cy")]
169 pub cy: u64,
170}
171
172#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
174pub struct Graphic {
175 #[serde(rename = "a:graphicData")]
176 pub graphic_data: GraphicData,
177}
178
179#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
181pub struct GraphicData {
182 #[serde(rename = "@uri")]
183 pub uri: String,
184
185 #[serde(rename = "c:chart")]
186 pub chart: ChartRef,
187}
188
189#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
191pub struct ChartRef {
192 #[serde(rename = "@xmlns:c")]
193 pub xmlns_c: String,
194
195 #[serde(rename = "@r:id")]
196 pub r_id: String,
197}
198
199#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
201pub struct Picture {
202 #[serde(rename = "xdr:nvPicPr")]
203 pub nv_pic_pr: NvPicPr,
204
205 #[serde(rename = "xdr:blipFill")]
206 pub blip_fill: BlipFill,
207
208 #[serde(rename = "xdr:spPr")]
209 pub sp_pr: SpPr,
210}
211
212#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
214pub struct NvPicPr {
215 #[serde(rename = "xdr:cNvPr")]
216 pub c_nv_pr: CNvPr,
217
218 #[serde(rename = "xdr:cNvPicPr")]
219 pub c_nv_pic_pr: CNvPicPr,
220}
221
222#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
224pub struct CNvPicPr {}
225
226#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
228pub struct BlipFill {
229 #[serde(rename = "a:blip")]
230 pub blip: Blip,
231
232 #[serde(rename = "a:stretch")]
233 pub stretch: Stretch,
234}
235
236#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
238pub struct Blip {
239 #[serde(rename = "@r:embed")]
240 pub r_embed: String,
241}
242
243#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
245pub struct Stretch {
246 #[serde(rename = "a:fillRect")]
247 pub fill_rect: FillRect,
248}
249
250#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
252pub struct FillRect {}
253
254#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
256pub struct SpPr {
257 #[serde(rename = "a:xfrm")]
258 pub xfrm: Xfrm,
259
260 #[serde(rename = "a:prstGeom")]
261 pub prst_geom: PrstGeom,
262}
263
264#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
266pub struct PrstGeom {
267 #[serde(rename = "@prst")]
268 pub prst: String,
269}
270
271#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
273pub struct Shape {
274 #[serde(rename = "xdr:nvSpPr")]
275 pub nv_sp_pr: NvSpPr,
276
277 #[serde(rename = "xdr:spPr")]
278 pub sp_pr: ShapeSpPr,
279
280 #[serde(rename = "xdr:txBody", skip_serializing_if = "Option::is_none")]
281 pub tx_body: Option<TxBody>,
282}
283
284#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
286pub struct NvSpPr {
287 #[serde(rename = "xdr:cNvPr")]
288 pub c_nv_pr: CNvPr,
289
290 #[serde(rename = "xdr:cNvSpPr")]
291 pub c_nv_sp_pr: CNvSpPr,
292}
293
294#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
296pub struct CNvSpPr {}
297
298#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
300pub struct ShapeSpPr {
301 #[serde(rename = "a:xfrm")]
302 pub xfrm: Xfrm,
303
304 #[serde(rename = "a:prstGeom")]
305 pub prst_geom: PrstGeom,
306
307 #[serde(rename = "a:solidFill", skip_serializing_if = "Option::is_none")]
308 pub solid_fill: Option<SolidFill>,
309
310 #[serde(rename = "a:ln", skip_serializing_if = "Option::is_none")]
311 pub ln: Option<Ln>,
312}
313
314#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
316pub struct SolidFill {
317 #[serde(rename = "a:srgbClr")]
318 pub srgb_clr: SrgbClr,
319}
320
321#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
323pub struct SrgbClr {
324 #[serde(rename = "@val")]
325 pub val: String,
326}
327
328#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
330pub struct Ln {
331 #[serde(rename = "@w", skip_serializing_if = "Option::is_none")]
332 pub w: Option<u64>,
333
334 #[serde(rename = "a:solidFill", skip_serializing_if = "Option::is_none")]
335 pub solid_fill: Option<SolidFill>,
336}
337
338#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
340pub struct TxBody {
341 #[serde(rename = "a:bodyPr")]
342 pub body_pr: BodyPr,
343
344 #[serde(rename = "a:lstStyle")]
345 pub lst_style: LstStyle,
346
347 #[serde(rename = "a:p")]
348 pub paragraphs: Vec<Paragraph>,
349}
350
351#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
353pub struct BodyPr {}
354
355#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
357pub struct LstStyle {}
358
359#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
361pub struct Paragraph {
362 #[serde(rename = "a:r", default, skip_serializing_if = "Vec::is_empty")]
363 pub runs: Vec<TextRun>,
364}
365
366#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
368pub struct TextRun {
369 #[serde(rename = "a:rPr", skip_serializing_if = "Option::is_none")]
370 pub r_pr: Option<RunProperties>,
371
372 #[serde(rename = "a:t")]
373 pub t: String,
374}
375
376#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
378pub struct RunProperties {
379 #[serde(rename = "@lang", skip_serializing_if = "Option::is_none")]
380 pub lang: Option<String>,
381
382 #[serde(rename = "@sz", skip_serializing_if = "Option::is_none")]
383 pub sz: Option<u32>,
384}
385
386#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
388pub struct ClientData {}
389
390#[cfg(test)]
391mod tests {
392 use super::*;
393
394 #[test]
395 fn test_ws_dr_default() {
396 let dr = WsDr::default();
397 assert_eq!(dr.xmlns_xdr, namespaces::DRAWING_ML_SPREADSHEET);
398 assert_eq!(dr.xmlns_a, namespaces::DRAWING_ML);
399 assert_eq!(dr.xmlns_r, namespaces::RELATIONSHIPS);
400 assert!(dr.two_cell_anchors.is_empty());
401 assert!(dr.one_cell_anchors.is_empty());
402 }
403
404 #[test]
405 fn test_marker_type_serialize() {
406 let marker = MarkerType {
407 col: 1,
408 col_off: 0,
409 row: 2,
410 row_off: 0,
411 };
412 let xml = quick_xml::se::to_string(&marker).unwrap();
413 assert!(xml.contains("<xdr:col>1</xdr:col>"));
414 assert!(xml.contains("<xdr:row>2</xdr:row>"));
415 }
416
417 #[test]
418 fn test_extent_serialize() {
419 let ext = Extent {
420 cx: 9525000,
421 cy: 4762500,
422 };
423 let xml = quick_xml::se::to_string(&ext).unwrap();
424 assert!(xml.contains("cx=\"9525000\""));
425 assert!(xml.contains("cy=\"4762500\""));
426 }
427
428 #[test]
429 fn test_chart_ref_serialize() {
430 let chart_ref = ChartRef {
431 xmlns_c: namespaces::DRAWING_ML_CHART.to_string(),
432 r_id: "rId1".to_string(),
433 };
434 let xml = quick_xml::se::to_string(&chart_ref).unwrap();
435 assert!(xml.contains("r:id=\"rId1\""));
436 }
437
438 #[test]
439 fn test_blip_serialize() {
440 let blip = Blip {
441 r_embed: "rId2".to_string(),
442 };
443 let xml = quick_xml::se::to_string(&blip).unwrap();
444 assert!(xml.contains("r:embed=\"rId2\""));
445 }
446
447 #[test]
448 fn test_prst_geom_serialize() {
449 let geom = PrstGeom {
450 prst: "rect".to_string(),
451 };
452 let xml = quick_xml::se::to_string(&geom).unwrap();
453 assert!(xml.contains("prst=\"rect\""));
454 }
455}