docx-rs/docx-core/src/documents/elements/comment.rs

140 lines
3.5 KiB
Rust

use serde::ser::{SerializeStruct, Serializer};
use serde::Serialize;
use crate::documents::*;
use crate::xml_builder::*;
#[derive(Serialize, Debug, Clone, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct Comment {
pub id: usize,
pub author: String,
pub date: String,
pub children: Vec<CommentChild>,
pub parent_comment_id: Option<usize>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum CommentChild {
Paragraph(Paragraph),
Table(Table),
}
impl Serialize for CommentChild {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match *self {
CommentChild::Paragraph(ref p) => {
let mut t = serializer.serialize_struct("Paragraph", 2)?;
t.serialize_field("type", "paragraph")?;
t.serialize_field("data", p)?;
t.end()
}
CommentChild::Table(ref c) => {
let mut t = serializer.serialize_struct("Table", 2)?;
t.serialize_field("type", "table")?;
t.serialize_field("data", c)?;
t.end()
}
}
}
}
impl Default for Comment {
fn default() -> Comment {
Comment {
id: 1,
author: "unnamed".to_owned(),
date: "1970-01-01T00:00:00Z".to_owned(),
children: vec![],
parent_comment_id: None,
}
}
}
impl Comment {
pub fn new(id: usize) -> Comment {
Self {
id,
..Default::default()
}
}
pub fn author(mut self, author: impl Into<String>) -> Comment {
self.author = author.into();
self
}
pub fn date(mut self, date: impl Into<String>) -> Comment {
self.date = date.into();
self
}
pub fn add_paragraph(mut self, p: Paragraph) -> Self {
self.children.push(CommentChild::Paragraph(p));
self
}
pub fn add_table(mut self, t: Table) -> Self {
self.children.push(CommentChild::Table(t));
self
}
pub fn parent_comment_id(mut self, parent_comment_id: usize) -> Comment {
self.parent_comment_id = Some(parent_comment_id);
self
}
pub fn id(&self) -> usize {
self.id
}
}
impl BuildXML for CommentChild {
fn build(&self) -> Vec<u8> {
match self {
CommentChild::Paragraph(v) => v.build(),
CommentChild::Table(v) => v.build(),
}
}
}
impl BuildXML for Comment {
fn build(&self) -> Vec<u8> {
XMLBuilder::new()
.open_comment(&format!("{}", self.id), &self.author, &self.date, "")
.add_children(&self.children)
.close()
.build()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[cfg(test)]
use pretty_assertions::assert_eq;
use std::str;
#[test]
fn test_comment_default() {
let b = Comment::new(1).build();
assert_eq!(
str::from_utf8(&b).unwrap(),
r#"<w:comment w:id="1" w:author="unnamed" w:date="1970-01-01T00:00:00Z" w:initials="" />"#
);
}
#[test]
fn test_comment_with_default_paragraph() {
let b = Comment::new(1).add_paragraph(Paragraph::new()).build();
assert_eq!(
str::from_utf8(&b).unwrap(),
r#"<w:comment w:id="1" w:author="unnamed" w:date="1970-01-01T00:00:00Z" w:initials=""><w:p w14:paraId="12345678"><w:pPr><w:rPr /></w:pPr></w:p></w:comment>"#
);
}
}