2020-04-07 04:24:56 +03:00
|
|
|
use super::{Break, DeleteText, Drawing, RunProperty, Tab, Text};
|
2020-02-11 10:01:39 +02:00
|
|
|
use serde::ser::{SerializeStruct, Serializer};
|
2020-04-07 04:24:56 +03:00
|
|
|
use serde::Serialize;
|
2020-02-11 10:01:39 +02:00
|
|
|
|
2019-11-07 09:08:59 +02:00
|
|
|
use crate::documents::BuildXML;
|
2019-11-13 09:51:58 +02:00
|
|
|
use crate::types::BreakType;
|
2019-11-07 09:08:59 +02:00
|
|
|
use crate::xml_builder::*;
|
|
|
|
|
2020-04-07 04:24:56 +03:00
|
|
|
#[derive(Serialize, Debug, Clone, PartialEq)]
|
2020-02-11 10:01:39 +02:00
|
|
|
#[serde(rename_all = "camelCase")]
|
2019-12-08 21:14:27 +02:00
|
|
|
pub struct Run {
|
2019-12-11 07:12:22 +02:00
|
|
|
pub run_property: RunProperty,
|
|
|
|
pub children: Vec<RunChild>,
|
2019-11-13 09:51:58 +02:00
|
|
|
}
|
|
|
|
|
2019-12-08 21:14:27 +02:00
|
|
|
impl Default for Run {
|
2019-11-13 09:51:58 +02:00
|
|
|
fn default() -> Self {
|
|
|
|
let run_property = RunProperty::new();
|
|
|
|
Self {
|
|
|
|
run_property,
|
|
|
|
children: vec![],
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-07 04:24:56 +03:00
|
|
|
#[derive(Debug, Clone, PartialEq)]
|
2019-12-08 21:14:27 +02:00
|
|
|
pub enum RunChild {
|
|
|
|
Text(Text),
|
2019-12-13 17:47:47 +02:00
|
|
|
DeleteText(DeleteText),
|
2019-11-13 09:51:58 +02:00
|
|
|
Tab(Tab),
|
|
|
|
Break(Break),
|
2020-04-07 04:24:56 +03:00
|
|
|
Drawing(Drawing),
|
2019-11-07 09:08:59 +02:00
|
|
|
}
|
|
|
|
|
2020-02-11 10:01:39 +02:00
|
|
|
impl Serialize for RunChild {
|
|
|
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
|
|
where
|
|
|
|
S: Serializer,
|
|
|
|
{
|
|
|
|
match *self {
|
|
|
|
RunChild::Text(ref s) => {
|
|
|
|
let mut t = serializer.serialize_struct("Text", 2)?;
|
|
|
|
t.serialize_field("type", "text")?;
|
|
|
|
t.serialize_field("data", s)?;
|
|
|
|
t.end()
|
|
|
|
}
|
|
|
|
RunChild::DeleteText(ref s) => {
|
|
|
|
let mut t = serializer.serialize_struct("DeleteText", 2)?;
|
|
|
|
t.serialize_field("type", "deleteText")?;
|
|
|
|
t.serialize_field("data", s)?;
|
|
|
|
t.end()
|
|
|
|
}
|
|
|
|
RunChild::Tab(_) => {
|
|
|
|
let mut t = serializer.serialize_struct("Tab", 1)?;
|
|
|
|
t.serialize_field("type", "tab")?;
|
|
|
|
t.end()
|
|
|
|
}
|
|
|
|
RunChild::Break(ref s) => {
|
|
|
|
let mut t = serializer.serialize_struct("Break", 2)?;
|
|
|
|
t.serialize_field("type", "break")?;
|
|
|
|
t.serialize_field("data", s)?;
|
|
|
|
t.end()
|
|
|
|
}
|
2020-04-07 04:24:56 +03:00
|
|
|
RunChild::Drawing(ref s) => {
|
|
|
|
let mut t = serializer.serialize_struct("Drawing", 2)?;
|
|
|
|
t.serialize_field("type", "drawing")?;
|
|
|
|
t.serialize_field("data", s)?;
|
|
|
|
t.end()
|
|
|
|
}
|
2020-02-11 10:01:39 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-08 21:14:27 +02:00
|
|
|
impl Run {
|
|
|
|
pub fn new() -> Run {
|
2019-11-07 09:08:59 +02:00
|
|
|
Run {
|
|
|
|
..Default::default()
|
|
|
|
}
|
|
|
|
}
|
2019-11-11 08:36:26 +02:00
|
|
|
|
2020-02-11 10:01:39 +02:00
|
|
|
pub fn add_text(mut self, text: impl Into<String>) -> Run {
|
2019-11-13 09:51:58 +02:00
|
|
|
self.children.push(RunChild::Text(Text::new(text)));
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2020-02-11 10:01:39 +02:00
|
|
|
pub fn add_delete_text(mut self, text: impl Into<String>) -> Run {
|
2019-12-20 11:53:26 +02:00
|
|
|
self.children
|
|
|
|
.push(RunChild::DeleteText(DeleteText::new(text)));
|
2019-11-15 11:15:43 +02:00
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2019-12-08 21:14:27 +02:00
|
|
|
pub fn add_tab(mut self) -> Run {
|
2019-11-13 09:51:58 +02:00
|
|
|
self.children.push(RunChild::Tab(Tab::new()));
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2020-04-07 04:24:56 +03:00
|
|
|
pub fn add_drawing(mut self, d: Drawing) -> Run {
|
|
|
|
self.children.push(RunChild::Drawing(d));
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2019-12-08 21:14:27 +02:00
|
|
|
pub fn add_break(mut self, break_type: BreakType) -> Run {
|
2019-11-13 09:51:58 +02:00
|
|
|
self.children.push(RunChild::Break(Break::new(break_type)));
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2019-12-08 21:14:27 +02:00
|
|
|
pub fn size(mut self, size: usize) -> Run {
|
2019-11-11 08:36:26 +02:00
|
|
|
self.run_property = self.run_property.size(size);
|
|
|
|
self
|
|
|
|
}
|
2019-11-13 09:08:25 +02:00
|
|
|
|
2019-12-08 21:14:27 +02:00
|
|
|
pub fn color(mut self, color: impl Into<String>) -> Run {
|
2019-11-13 09:08:25 +02:00
|
|
|
self.run_property = self.run_property.color(color);
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2019-12-08 21:14:27 +02:00
|
|
|
pub fn highlight(mut self, color: impl Into<String>) -> Run {
|
2019-11-13 09:08:25 +02:00
|
|
|
self.run_property = self.run_property.highlight(color);
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2019-12-08 21:14:27 +02:00
|
|
|
pub fn bold(mut self) -> Run {
|
2019-11-13 09:08:25 +02:00
|
|
|
self.run_property = self.run_property.bold();
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2019-12-08 21:14:27 +02:00
|
|
|
pub fn italic(mut self) -> Run {
|
2019-11-13 09:08:25 +02:00
|
|
|
self.run_property = self.run_property.italic();
|
|
|
|
self
|
|
|
|
}
|
2019-12-04 09:28:11 +02:00
|
|
|
|
2019-12-08 21:14:27 +02:00
|
|
|
pub fn underline(mut self, line_type: impl Into<String>) -> Run {
|
2019-12-04 09:28:11 +02:00
|
|
|
self.run_property = self.run_property.underline(line_type);
|
|
|
|
self
|
|
|
|
}
|
2019-12-13 17:47:47 +02:00
|
|
|
|
|
|
|
pub fn vanish(mut self) -> Run {
|
|
|
|
self.run_property = self.run_property.vanish();
|
|
|
|
self
|
|
|
|
}
|
2019-11-07 09:08:59 +02:00
|
|
|
}
|
|
|
|
|
2019-12-08 21:14:27 +02:00
|
|
|
impl BuildXML for Run {
|
2019-11-07 09:08:59 +02:00
|
|
|
fn build(&self) -> Vec<u8> {
|
|
|
|
let b = XMLBuilder::new();
|
2019-11-13 09:51:58 +02:00
|
|
|
let mut b = b.open_run().add_child(&self.run_property);
|
|
|
|
for c in &self.children {
|
|
|
|
match c {
|
|
|
|
RunChild::Text(t) => b = b.add_child(t),
|
2019-12-13 17:47:47 +02:00
|
|
|
RunChild::DeleteText(t) => b = b.add_child(t),
|
2019-11-13 09:51:58 +02:00
|
|
|
RunChild::Tab(t) => b = b.add_child(t),
|
|
|
|
RunChild::Break(t) => b = b.add_child(t),
|
2020-04-07 04:24:56 +03:00
|
|
|
RunChild::Drawing(t) => b = b.add_child(t),
|
2019-11-13 09:51:58 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
b.close().build()
|
2019-11-07 09:08:59 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
|
2020-02-11 10:01:39 +02:00
|
|
|
use super::super::*;
|
2019-11-07 09:08:59 +02:00
|
|
|
use super::*;
|
|
|
|
#[cfg(test)]
|
|
|
|
use pretty_assertions::assert_eq;
|
|
|
|
use std::str;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_build() {
|
2019-11-13 09:51:58 +02:00
|
|
|
let b = Run::new().add_text("Hello").build();
|
2019-11-07 09:08:59 +02:00
|
|
|
assert_eq!(
|
|
|
|
str::from_utf8(&b).unwrap(),
|
2019-11-11 06:05:07 +02:00
|
|
|
r#"<w:r><w:rPr /><w:t xml:space="preserve">Hello</w:t></w:r>"#
|
2019-11-07 09:08:59 +02:00
|
|
|
);
|
|
|
|
}
|
2019-12-04 09:28:11 +02:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_underline() {
|
|
|
|
let b = Run::new().add_text("Hello").underline("single").build();
|
|
|
|
assert_eq!(
|
|
|
|
str::from_utf8(&b).unwrap(),
|
|
|
|
r#"<w:r><w:rPr><w:u w:val="single" /></w:rPr><w:t xml:space="preserve">Hello</w:t></w:r>"#
|
|
|
|
);
|
|
|
|
}
|
2020-02-11 10:01:39 +02:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_child_json() {
|
|
|
|
let c = RunChild::Text(Text::new("Hello"));
|
|
|
|
assert_eq!(
|
|
|
|
serde_json::to_string(&c).unwrap(),
|
|
|
|
r#"{"type":"text","data":{"preserveSpace":true,"text":"Hello"}}"#
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_run_json() {
|
|
|
|
let run = Run {
|
|
|
|
children: vec![
|
|
|
|
RunChild::Tab(Tab::new()),
|
|
|
|
RunChild::Text(Text::new("Hello")),
|
|
|
|
RunChild::Break(Break::new(BreakType::Page)),
|
|
|
|
RunChild::DeleteText(DeleteText::new("deleted")),
|
|
|
|
],
|
|
|
|
run_property: RunProperty {
|
|
|
|
sz: Some(Sz::new(30)),
|
|
|
|
sz_cs: Some(SzCs::new(30)),
|
|
|
|
color: Some(Color::new("C9211E")),
|
|
|
|
highlight: Some(Highlight::new("yellow")),
|
|
|
|
underline: Some(Underline::new("single")),
|
|
|
|
bold: Some(Bold::new()),
|
|
|
|
bold_cs: Some(BoldCs::new()),
|
|
|
|
italic: Some(Italic::new()),
|
|
|
|
italic_cs: Some(ItalicCs::new()),
|
|
|
|
vanish: Some(Vanish::new()),
|
|
|
|
},
|
|
|
|
};
|
|
|
|
assert_eq!(
|
|
|
|
serde_json::to_string(&run).unwrap(),
|
|
|
|
r#"{"runProperty":{"sz":30,"szCs":30,"color":"C9211E","highlight":"yellow","underline":"single","bold":true,"boldCs":true,"italic":true,"italicCs":true,"vanish":true},"children":[{"type":"tab"},{"type":"text","data":{"preserveSpace":true,"text":"Hello"}},{"type":"break","data":{"breakType":"page"}},{"type":"deleteText","data":{"text":"deleted","preserveSpace":true}}]}"#
|
|
|
|
);
|
|
|
|
}
|
2019-11-07 09:08:59 +02:00
|
|
|
}
|