Skip to main content

docx_rs/documents/elements/
move_to.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 MoveToChild {
12    Run(Box<Run>),
13    Delete(Delete),
14    CommentStart(Box<CommentRangeStart>),
15    CommentEnd(CommentRangeEnd),
16}
17
18impl BuildXML for MoveToChild {
19    fn build_to<W: Write>(
20        &self,
21        stream: crate::xml::writer::EventWriter<W>,
22    ) -> crate::xml::writer::Result<crate::xml::writer::EventWriter<W>> {
23        match self {
24            MoveToChild::Run(v) => v.build_to(stream),
25            MoveToChild::Delete(v) => v.build_to(stream),
26            MoveToChild::CommentStart(v) => v.build_to(stream),
27            MoveToChild::CommentEnd(v) => v.build_to(stream),
28        }
29    }
30}
31
32impl Serialize for MoveToChild {
33    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
34    where
35        S: Serializer,
36    {
37        match *self {
38            MoveToChild::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            MoveToChild::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            MoveToChild::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            MoveToChild::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 MoveTo {
68    pub children: Vec<MoveToChild>,
69    pub author: String,
70    pub date: String,
71}
72
73impl Default for MoveTo {
74    fn default() -> MoveTo {
75        MoveTo {
76            author: "unnamed".to_owned(),
77            date: "1970-01-01T00:00:00Z".to_owned(),
78            children: vec![],
79        }
80    }
81}
82
83impl MoveTo {
84    pub fn new(run: Run) -> MoveTo {
85        Self {
86            children: vec![MoveToChild::Run(Box::new(run))],
87            ..Default::default()
88        }
89    }
90
91    pub fn new_with_empty() -> MoveTo {
92        Self {
93            ..Default::default()
94        }
95    }
96
97    pub fn add_run(mut self, run: Run) -> MoveTo {
98        self.children.push(MoveToChild::Run(Box::new(run)));
99        self
100    }
101
102    pub fn add_delete(mut self, del: Delete) -> MoveTo {
103        self.children.push(MoveToChild::Delete(del));
104        self
105    }
106
107    pub fn add_child(mut self, c: MoveToChild) -> MoveTo {
108        self.children.push(c);
109        self
110    }
111
112    pub fn add_comment_start(mut self, comment: Comment) -> Self {
113        self.children
114            .push(MoveToChild::CommentStart(Box::new(CommentRangeStart::new(
115                comment,
116            ))));
117        self
118    }
119
120    pub fn add_comment_end(mut self, id: usize) -> Self {
121        self.children
122            .push(MoveToChild::CommentEnd(CommentRangeEnd::new(id)));
123        self
124    }
125
126    pub fn author(mut self, author: impl Into<String>) -> MoveTo {
127        self.author = escape::escape_owned(author.into());
128        self
129    }
130
131    pub fn date(mut self, date: impl Into<String>) -> MoveTo {
132        self.date = date.into();
133        self
134    }
135}
136
137impl HistoryId for MoveTo {}
138
139impl BuildXML for MoveTo {
140    fn build_to<W: Write>(
141        &self,
142        stream: crate::xml::writer::EventWriter<W>,
143    ) -> crate::xml::writer::Result<crate::xml::writer::EventWriter<W>> {
144        let id = self.generate();
145        XMLBuilder::from(stream)
146            .open_move_to(id.as_ref(), &self.author, &self.date)?
147            .add_children(&self.children)?
148            .close()?
149            .into_inner()
150    }
151}
152
153#[cfg(test)]
154mod tests {
155
156    use super::*;
157    #[cfg(test)]
158    use pretty_assertions::assert_eq;
159    use std::str;
160
161    #[test]
162    fn test_move_to_default() {
163        let b = MoveTo::new(Run::new()).build();
164        assert_eq!(
165            str::from_utf8(&b).unwrap(),
166            r#"<w:moveTo w:id="123" w:author="unnamed" w:date="1970-01-01T00:00:00Z"><w:r><w:rPr /></w:r></w:moveTo>"#
167        );
168    }
169}