docx_rs/documents/elements/
insert.rs

1use serde::ser::{SerializeStruct, Serializer};
2use serde::Serialize;
3use std::io::Write;
4
5use super::*;
6
7use crate::documents::{BuildXML, HistoryId, Run};
8use crate::{escape, xml_builder::*};
9
10#[derive(Debug, Clone, PartialEq)]
11pub enum InsertChild {
12    Run(Box<Run>),
13    Delete(Delete),
14    CommentStart(Box<CommentRangeStart>),
15    CommentEnd(CommentRangeEnd),
16}
17
18impl BuildXML for InsertChild {
19    fn build_to<W: Write>(
20        &self,
21        stream: xml::writer::EventWriter<W>,
22    ) -> xml::writer::Result<xml::writer::EventWriter<W>> {
23        match self {
24            InsertChild::Run(v) => v.build_to(stream),
25            InsertChild::Delete(v) => v.build_to(stream),
26            InsertChild::CommentStart(v) => v.build_to(stream),
27            InsertChild::CommentEnd(v) => v.build_to(stream),
28        }
29    }
30}
31
32impl Serialize for InsertChild {
33    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
34    where
35        S: Serializer,
36    {
37        match *self {
38            InsertChild::Run(ref r) => {
39                let mut t = serializer.serialize_struct("Run", 2)?;
40                t.serialize_field("type", "run")?;
41                t.serialize_field("data", r)?;
42                t.end()
43            }
44            InsertChild::Delete(ref r) => {
45                let mut t = serializer.serialize_struct("Delete", 2)?;
46                t.serialize_field("type", "delete")?;
47                t.serialize_field("data", r)?;
48                t.end()
49            }
50            InsertChild::CommentStart(ref r) => {
51                let mut t = serializer.serialize_struct("CommentRangeStart", 2)?;
52                t.serialize_field("type", "commentRangeStart")?;
53                t.serialize_field("data", r)?;
54                t.end()
55            }
56            InsertChild::CommentEnd(ref r) => {
57                let mut t = serializer.serialize_struct("CommentRangeEnd", 2)?;
58                t.serialize_field("type", "commentRangeEnd")?;
59                t.serialize_field("data", r)?;
60                t.end()
61            }
62        }
63    }
64}
65
66#[derive(Serialize, Debug, Clone, PartialEq)]
67pub struct Insert {
68    pub children: Vec<InsertChild>,
69    pub author: String,
70    pub date: String,
71}
72
73impl Default for Insert {
74    fn default() -> Insert {
75        Insert {
76            author: "unnamed".to_owned(),
77            date: "1970-01-01T00:00:00Z".to_owned(),
78            children: vec![],
79        }
80    }
81}
82
83impl Insert {
84    pub fn new(run: Run) -> Insert {
85        Self {
86            children: vec![InsertChild::Run(Box::new(run))],
87            ..Default::default()
88        }
89    }
90
91    pub fn new_with_empty() -> Insert {
92        Self {
93            ..Default::default()
94        }
95    }
96
97    pub fn new_with_del(del: Delete) -> Insert {
98        Self {
99            children: vec![InsertChild::Delete(del)],
100            ..Default::default()
101        }
102    }
103
104    pub fn add_run(mut self, run: Run) -> Insert {
105        self.children.push(InsertChild::Run(Box::new(run)));
106        self
107    }
108
109    pub fn add_delete(mut self, del: Delete) -> Insert {
110        self.children.push(InsertChild::Delete(del));
111        self
112    }
113
114    pub fn add_child(mut self, c: InsertChild) -> Insert {
115        self.children.push(c);
116        self
117    }
118
119    pub fn add_comment_start(mut self, comment: Comment) -> Self {
120        self.children
121            .push(InsertChild::CommentStart(Box::new(CommentRangeStart::new(
122                comment,
123            ))));
124        self
125    }
126
127    pub fn add_comment_end(mut self, id: usize) -> Self {
128        self.children
129            .push(InsertChild::CommentEnd(CommentRangeEnd::new(id)));
130        self
131    }
132
133    pub fn author(mut self, author: impl Into<String>) -> Insert {
134        self.author = escape::escape(&author.into());
135        self
136    }
137
138    pub fn date(mut self, date: impl Into<String>) -> Insert {
139        self.date = date.into();
140        self
141    }
142}
143
144impl HistoryId for Insert {}
145
146impl BuildXML for Insert {
147    fn build_to<W: Write>(
148        &self,
149        stream: xml::writer::EventWriter<W>,
150    ) -> xml::writer::Result<xml::writer::EventWriter<W>> {
151        XMLBuilder::from(stream)
152            .open_insert(&self.generate(), &self.author, &self.date)?
153            .add_children(&self.children)?
154            .close()?
155            .into_inner()
156    }
157}
158
159#[cfg(test)]
160mod tests {
161
162    use super::*;
163    #[cfg(test)]
164    use pretty_assertions::assert_eq;
165    use std::str;
166
167    #[test]
168    fn test_ins_default() {
169        let b = Insert::new(Run::new()).build();
170        assert_eq!(
171            str::from_utf8(&b).unwrap(),
172            r#"<w:ins w:id="123" w:author="unnamed" w:date="1970-01-01T00:00:00Z"><w:r><w:rPr /></w:r></w:ins>"#
173        );
174    }
175}