docx_rs/documents/elements/
a_graphic_data.rs

1use super::*;
2use serde::ser::{SerializeStruct, Serializer};
3use serde::Serialize;
4use std::io::Write;
5use std::str::FromStr;
6
7use crate::documents::BuildXML;
8use crate::xml_builder::*;
9
10/*
11  20.1.2.2.17
12  graphicData (Graphic Object Data)
13  This element specifies the reference to a graphic object within the document. This graphic object is provided
14  entirely by the document authors who choose to persist this data within the document.
15*/
16#[derive(Debug, Clone, Serialize, PartialEq)]
17#[serde(rename_all = "camelCase")]
18pub struct AGraphicData {
19    pub data_type: GraphicDataType,
20    pub children: Vec<GraphicDataChild>,
21}
22
23#[derive(Debug, Clone, PartialEq)]
24pub enum GraphicDataChild {
25    Shape(WpsShape),
26    Pic(Pic),
27}
28
29impl Serialize for GraphicDataChild {
30    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
31    where
32        S: Serializer,
33    {
34        match *self {
35            GraphicDataChild::Shape(ref s) => {
36                let mut t = serializer.serialize_struct("Shape", 2)?;
37                t.serialize_field("type", "shape")?;
38                t.serialize_field("data", s)?;
39                t.end()
40            }
41            GraphicDataChild::Pic(ref s) => {
42                let mut t = serializer.serialize_struct("Pic", 2)?;
43                t.serialize_field("type", "pic")?;
44                t.serialize_field("data", s)?;
45                t.end()
46            }
47        }
48    }
49}
50
51impl GraphicDataType {
52    fn to_uri(&self) -> &str {
53        match *self {
54            GraphicDataType::Picture => "http://schemas.openxmlformats.org/drawingml/2006/picture",
55            GraphicDataType::WpShape => {
56                "http://schemas.microsoft.com/office/word/2010/wordprocessingShape"
57            }
58            _ => "",
59        }
60    }
61}
62
63impl FromStr for GraphicDataType {
64    type Err = ();
65    fn from_str(s: &str) -> Result<Self, Self::Err> {
66        if s.ends_with("picture") {
67            return Ok(GraphicDataType::Picture);
68        }
69        if s.ends_with("wordprocessingShape") {
70            return Ok(GraphicDataType::WpShape);
71        }
72        Ok(GraphicDataType::Unsupported)
73    }
74}
75
76#[derive(Debug, Clone, Serialize, PartialEq)]
77#[serde(rename_all = "camelCase")]
78pub enum GraphicDataType {
79    Picture,
80    WpShape,
81    Unsupported,
82}
83
84impl AGraphicData {
85    pub fn new(data_type: GraphicDataType) -> AGraphicData {
86        AGraphicData {
87            data_type,
88            children: vec![],
89        }
90    }
91
92    pub fn add_shape(mut self, shape: WpsShape) -> Self {
93        self.children.push(GraphicDataChild::Shape(shape));
94        self
95    }
96}
97
98impl BuildXML for AGraphicData {
99    fn build_to<W: Write>(
100        &self,
101        stream: xml::writer::EventWriter<W>,
102    ) -> xml::writer::Result<xml::writer::EventWriter<W>> {
103        XMLBuilder::from(stream)
104            .open_graphic_data(self.data_type.to_uri())?
105            .apply_each(&self.children, |ch, b| match ch {
106                GraphicDataChild::Shape(t) => b.add_child(t),
107                GraphicDataChild::Pic(t) => b.add_child(t),
108            })?
109            .close()?
110            .into_inner()
111    }
112}