use serde::ser::{SerializeStruct, Serializer}; use serde::Serialize; use std::io::Write; use crate::xml_builder::*; use crate::{documents::*, escape}; #[derive(Serialize, Debug, Clone, PartialEq)] pub struct Delete { pub author: String, pub date: String, pub children: Vec, } #[derive(Debug, Clone, PartialEq)] pub enum DeleteChild { Run(Run), CommentStart(Box), CommentEnd(CommentRangeEnd), } impl Serialize for DeleteChild { fn serialize(&self, serializer: S) -> Result where S: Serializer, { match *self { DeleteChild::Run(ref r) => { let mut t = serializer.serialize_struct("Run", 2)?; t.serialize_field("type", "run")?; t.serialize_field("data", r)?; t.end() } DeleteChild::CommentStart(ref r) => { let mut t = serializer.serialize_struct("CommentRangeStart", 2)?; t.serialize_field("type", "commentRangeStart")?; t.serialize_field("data", r)?; t.end() } DeleteChild::CommentEnd(ref r) => { let mut t = serializer.serialize_struct("CommentRangeEnd", 2)?; t.serialize_field("type", "commentRangeEnd")?; t.serialize_field("data", r)?; t.end() } } } } impl Default for Delete { fn default() -> Delete { Delete { author: "unnamed".to_owned(), date: "1970-01-01T00:00:00Z".to_owned(), children: vec![], } } } impl Delete { pub fn new() -> Delete { Self { children: vec![], ..Default::default() } } pub fn add_run(mut self, run: Run) -> Delete { self.children.push(DeleteChild::Run(run)); self } pub fn add_comment_start(mut self, comment: Comment) -> Delete { self.children .push(DeleteChild::CommentStart(Box::new(CommentRangeStart::new( comment, )))); self } pub fn add_comment_end(mut self, id: usize) -> Delete { self.children .push(DeleteChild::CommentEnd(CommentRangeEnd::new(id))); self } pub fn author(mut self, author: impl Into) -> Delete { self.author = escape::escape(&author.into()); self } pub fn date(mut self, date: impl Into) -> Delete { self.date = date.into(); self } } impl HistoryId for Delete {} impl BuildXML for Delete { fn build_to( &self, stream: xml::writer::EventWriter, ) -> xml::writer::Result> { let id = self.generate(); XMLBuilder::from(stream) .open_delete(&id, &self.author, &self.date)? .apply_each(&self.children, |ch, b| match ch { DeleteChild::Run(t) => b.add_child(t), DeleteChild::CommentStart(c) => b.add_child(&c), DeleteChild::CommentEnd(c) => b.add_child(c), })? .close()? .into_inner() } } #[cfg(test)] mod tests { use super::*; #[cfg(test)] use pretty_assertions::assert_eq; use std::str; #[test] fn test_delete_default() { let b = Delete::new().add_run(Run::new()).build(); assert_eq!( str::from_utf8(&b).unwrap(), r#""# ); } }