parent
ec904987be
commit
1941af9ef7
|
@ -1,12 +1,51 @@
|
|||
use serde::ser::{SerializeStruct, Serializer};
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::documents::{BuildXML, HistoryId, Run};
|
||||
use super::*;
|
||||
|
||||
use crate::documents::{BuildXML, HistoryId, Run};
|
||||
use crate::xml_builder::*;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum InsertChild {
|
||||
Run(Box<Run>),
|
||||
Delete(Delete),
|
||||
}
|
||||
|
||||
impl BuildXML for InsertChild {
|
||||
fn build(&self) -> Vec<u8> {
|
||||
match self {
|
||||
InsertChild::Run(v) => v.build(),
|
||||
InsertChild::Delete(v) => v.build(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for InsertChild {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
match *self {
|
||||
InsertChild::Run(ref r) => {
|
||||
let mut t = serializer.serialize_struct("Run", 2)?;
|
||||
t.serialize_field("type", "run")?;
|
||||
t.serialize_field("data", r)?;
|
||||
t.end()
|
||||
}
|
||||
InsertChild::Delete(ref r) => {
|
||||
let mut t = serializer.serialize_struct("Delete", 2)?;
|
||||
t.serialize_field("type", "delete")?;
|
||||
t.serialize_field("data", r)?;
|
||||
t.end()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Debug, Clone, PartialEq)]
|
||||
pub struct Insert {
|
||||
pub runs: Vec<Run>,
|
||||
pub children: Vec<InsertChild>,
|
||||
pub author: String,
|
||||
pub date: String,
|
||||
}
|
||||
|
@ -16,7 +55,7 @@ impl Default for Insert {
|
|||
Insert {
|
||||
author: "unnamed".to_owned(),
|
||||
date: "1970-01-01T00:00:00Z".to_owned(),
|
||||
runs: vec![],
|
||||
children: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,13 +63,36 @@ impl Default for Insert {
|
|||
impl Insert {
|
||||
pub fn new(run: Run) -> Insert {
|
||||
Self {
|
||||
runs: vec![run],
|
||||
children: vec![InsertChild::Run(Box::new(run))],
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_with_empty() -> Insert {
|
||||
Self {
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_with_del(del: Delete) -> Insert {
|
||||
Self {
|
||||
children: vec![InsertChild::Delete(del)],
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_run(mut self, run: Run) -> Insert {
|
||||
self.runs.push(run);
|
||||
self.children.push(InsertChild::Run(Box::new(run)));
|
||||
self
|
||||
}
|
||||
|
||||
pub fn add_delete(mut self, del: Delete) -> Insert {
|
||||
self.children.push(InsertChild::Delete(del));
|
||||
self
|
||||
}
|
||||
|
||||
pub fn add_child(mut self, c: InsertChild) -> Insert {
|
||||
self.children.push(c);
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -51,7 +113,7 @@ impl BuildXML for Insert {
|
|||
fn build(&self) -> Vec<u8> {
|
||||
XMLBuilder::new()
|
||||
.open_insert(&self.generate(), &self.author, &self.date)
|
||||
.add_children(&self.runs)
|
||||
.add_children(&self.children)
|
||||
.close()
|
||||
.build()
|
||||
}
|
||||
|
|
|
@ -290,7 +290,7 @@ mod tests {
|
|||
let p = Paragraph::new().add_insert(ins);
|
||||
assert_eq!(
|
||||
serde_json::to_string(&p).unwrap(),
|
||||
r#"{"id":"12345678","children":[{"type":"insert","data":{"runs":[{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"fonts":null},"children":[{"type":"text","data":{"preserveSpace":true,"text":"Hello"}}]}],"author":"unnamed","date":"1970-01-01T00:00:00Z"}}],"property":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"fonts":null},"style":null,"numberingProperty":null,"alignment":null,"indent":null},"hasNumbering":false}"#
|
||||
r#"{"id":"12345678","children":[{"type":"insert","data":{"children":[{"type":"run","data":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"fonts":null},"children":[{"type":"text","data":{"preserveSpace":true,"text":"Hello"}}]}}],"author":"unnamed","date":"1970-01-01T00:00:00Z"}}],"property":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"fonts":null},"style":null,"numberingProperty":null,"alignment":null,"indent":null},"hasNumbering":false}"#
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,25 +11,26 @@ impl ElementReader for Insert {
|
|||
r: &mut EventReader<R>,
|
||||
attrs: &[OwnedAttribute],
|
||||
) -> Result<Self, ReaderError> {
|
||||
let mut runs: Vec<Run> = vec![];
|
||||
let mut children: Vec<InsertChild> = vec![];
|
||||
loop {
|
||||
let e = r.next();
|
||||
match e {
|
||||
Ok(XmlEvent::StartElement { name, .. }) => {
|
||||
let e = XMLElement::from_str(&name.local_name).unwrap();
|
||||
if let XMLElement::Run = e {
|
||||
runs.push(Run::read(r, attrs)?);
|
||||
match e {
|
||||
XMLElement::Run => {
|
||||
children.push(InsertChild::Run(Box::new(Run::read(r, attrs)?)))
|
||||
}
|
||||
XMLElement::Delete => {
|
||||
children.push(InsertChild::Delete(Delete::read(r, attrs)?))
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
Ok(XmlEvent::EndElement { name, .. }) => {
|
||||
let e = XMLElement::from_str(&name.local_name).unwrap();
|
||||
if e == XMLElement::Insert {
|
||||
let run = if !runs.is_empty() {
|
||||
std::mem::replace(&mut runs[0], Run::new())
|
||||
} else {
|
||||
Run::new()
|
||||
};
|
||||
let mut ins = Insert::new(run);
|
||||
let mut ins = Insert::new_with_empty();
|
||||
for attr in attrs {
|
||||
let local_name = &attr.name.local_name;
|
||||
if local_name == "author" {
|
||||
|
@ -38,10 +39,8 @@ impl ElementReader for Insert {
|
|||
ins = ins.date(&attr.value);
|
||||
}
|
||||
}
|
||||
if runs.len() > 1 {
|
||||
for r in runs.into_iter().skip(1) {
|
||||
ins = ins.add_run(r);
|
||||
}
|
||||
for c in children.into_iter() {
|
||||
ins = ins.add_child(c);
|
||||
}
|
||||
return Ok(ins);
|
||||
}
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -32,10 +32,7 @@ export type ParagraphJSON = {
|
|||
export type InsertJSON = {
|
||||
type: "insert";
|
||||
data: {
|
||||
runs: {
|
||||
runProperty: RunPropertyJSON;
|
||||
children: RunChildJSON[];
|
||||
}[];
|
||||
children: (DeleteJSON | RunJSON)[];
|
||||
author: string;
|
||||
data: string;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue