docx_rs/documents/elements/
insert.rs1use 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}