From 4450e758b427f413a7dc7659ee868e0bf3c162d9 Mon Sep 17 00:00:00 2001 From: bokuweb Date: Mon, 9 Dec 2019 03:52:44 +0900 Subject: [PATCH] feat: Use String for wasm This is because wasm-bindgen does not support 'static for function Pleaase see https://github.com/rustwasm/wasm-bindgen/issues/1187 --- docx-core/src/documents/comments.rs | 12 +- docx-core/src/documents/doc_props/core.rs | 78 ++++++----- docx-core/src/documents/doc_props/mod.rs | 6 +- docx-core/src/documents/document.rs | 22 +-- .../src/documents/elements/bookmark_end.rs | 12 +- .../src/documents/elements/bookmark_start.rs | 17 ++- docx-core/src/documents/elements/comment.rs | 44 +++--- .../documents/elements/comment_range_end.rs | 12 +- .../documents/elements/comment_range_start.rs | 14 +- docx-core/src/documents/elements/delete.rs | 28 ++-- docx-core/src/documents/elements/insert.rs | 28 ++-- docx-core/src/documents/elements/level.rs | 20 +-- docx-core/src/documents/elements/level_jc.rs | 14 +- .../src/documents/elements/level_text.rs | 14 +- .../src/documents/elements/number_format.rs | 14 +- docx-core/src/documents/elements/numbering.rs | 25 ++-- docx-core/src/documents/elements/paragraph.rs | 60 ++++---- .../documents/elements/paragraph_property.rs | 2 +- docx-core/src/documents/elements/run.rs | 36 ++--- .../src/documents/elements/run_property.rs | 6 +- docx-core/src/documents/elements/table.rs | 12 +- .../src/documents/elements/table_cell.rs | 20 +-- docx-core/src/documents/elements/table_row.rs | 10 +- docx-core/src/documents/elements/text.rs | 10 +- docx-core/src/documents/mod.rs | 29 ++-- docx-core/src/documents/numberings.rs | 131 ++++++++++++++---- docx-core/src/documents/xml_docx.rs | 1 + docx-wasm/index.js | 6 +- docx-wasm/src/lib.rs | 47 +++++-- 29 files changed, 429 insertions(+), 301 deletions(-) diff --git a/docx-core/src/documents/comments.rs b/docx-core/src/documents/comments.rs index 2ab8d2197..bc111709a 100644 --- a/docx-core/src/documents/comments.rs +++ b/docx-core/src/documents/comments.rs @@ -3,26 +3,26 @@ use crate::documents::BuildXML; use crate::xml_builder::*; #[derive(Debug)] -pub struct Comments<'a> { - comments: Vec>, +pub struct Comments { + comments: Vec, } -impl<'a> Comments<'a> { +impl Comments { pub fn new() -> Self { Default::default() } - pub(crate) fn add_comments(&mut self, comments: Vec>) { + pub(crate) fn add_comments(&mut self, comments: Vec) { self.comments = comments; } } -impl<'a> Default for Comments<'a> { +impl Default for Comments { fn default() -> Self { Self { comments: vec![] } } } -impl<'a> BuildXML for Comments<'a> { +impl BuildXML for Comments { fn build(&self) -> Vec { let mut b = XMLBuilder::new().declaration(Some(true)).open_comments(); for c in &self.comments { diff --git a/docx-core/src/documents/doc_props/core.rs b/docx-core/src/documents/doc_props/core.rs index 9dcc6b622..b01258473 100644 --- a/docx-core/src/documents/doc_props/core.rs +++ b/docx-core/src/documents/doc_props/core.rs @@ -2,30 +2,30 @@ use crate::documents::BuildXML; use crate::xml_builder::*; #[derive(Debug)] -pub struct CoreProps<'a> { - config: CorePropsConfig<'a>, +pub struct CoreProps { + config: CorePropsConfig, } #[derive(Debug)] -pub struct CorePropsConfig<'a> { - created: Option<&'a str>, - creator: Option<&'a str>, - description: Option<&'a str>, - language: Option<&'a str>, - last_modified_by: Option<&'a str>, - modified: Option<&'a str>, +pub struct CorePropsConfig { + created: Option, + creator: Option, + description: Option, + language: Option, + last_modified_by: Option, + modified: Option, revision: Option, - subject: Option<&'a str>, - title: Option<&'a str>, + subject: Option, + title: Option, } -impl<'a> CoreProps<'a> { - pub(crate) fn new(config: CorePropsConfig<'a>) -> CoreProps { +impl CoreProps { + pub(crate) fn new(config: CorePropsConfig) -> CoreProps { CoreProps { config } } } -impl<'a> CorePropsConfig<'a> { +impl CorePropsConfig { pub fn new() -> Self { CorePropsConfig { created: None, @@ -41,7 +41,7 @@ impl<'a> CorePropsConfig<'a> { } } -impl<'a> BuildXML for CoreProps<'a> { +impl BuildXML for CoreProps { fn build(&self) -> Vec { let b = XMLBuilder::new(); let base = b.declaration(Some(true)).open_core_properties( @@ -58,32 +58,40 @@ impl<'a> BuildXML for CoreProps<'a> { "dcterms:W3CDTF", self.config .created - .map_or_else(|| "1970-01-01T00:00:00Z", |v| v), + .as_ref() + .map_or_else(|| "1970-01-01T00:00:00Z", |v| &v), + ) + .dc_creator( + self.config + .creator + .as_ref() + .map_or_else(|| "unknown", |v| &v), ) - .dc_creator(self.config.creator.map_or_else(|| "unknown", |v| v)) .cp_last_modified_by( self.config .last_modified_by - .map_or_else(|| "unknown", |v| v), + .as_ref() + .map_or_else(|| "unknown", |v| &v), ) .dcterms_modified( "dcterms:W3CDTF", self.config .modified - .map_or_else(|| "1970-01-01T00:00:00Z", |v| v), + .as_ref() + .map_or_else(|| "1970-01-01T00:00:00Z", |v| &v), ) .cp_revision(&self.config.revision.map_or_else(|| "1".to_owned(), convert)); - if let Some(v) = self.config.description { - base = base.dc_description(v); + if let Some(v) = self.config.description.as_ref() { + base = base.dc_description(&v); } - if let Some(v) = self.config.language { - base = base.dc_language(v); + if let Some(v) = self.config.language.as_ref() { + base = base.dc_language(&v); } - if let Some(v) = self.config.subject { - base = base.dc_subject(v); + if let Some(v) = self.config.subject.as_ref() { + base = base.dc_subject(&v); } - if let Some(v) = self.config.title { - base = base.dc_title(v); + if let Some(v) = self.config.title.as_ref() { + base = base.dc_title(&v); } base.close().build() } @@ -127,15 +135,15 @@ mod tests { #[test] fn test_configured_doc_props_core_build() { let c = CoreProps::new(CorePropsConfig { - created: Some("2019-01-01"), - creator: Some("foo"), - description: Some("bar"), - language: Some("en"), - last_modified_by: Some("go"), - modified: Some("2019-01-01"), + created: Some("2019-01-01".to_owned()), + creator: Some("foo".to_owned()), + description: Some("bar".to_owned()), + language: Some("en".to_owned()), + last_modified_by: Some("go".to_owned()), + modified: Some("2019-01-01".to_owned()), revision: Some(1), - subject: Some("subject"), - title: Some("title"), + subject: Some("subject".to_owned()), + title: Some("title".to_owned()), }); let b = c.build(); assert_eq!( diff --git a/docx-core/src/documents/doc_props/mod.rs b/docx-core/src/documents/doc_props/mod.rs index cbcd2f581..8301a6ffc 100644 --- a/docx-core/src/documents/doc_props/mod.rs +++ b/docx-core/src/documents/doc_props/mod.rs @@ -6,12 +6,12 @@ pub use self::core::*; use crate::documents::BuildXML; #[derive(Debug)] -pub(crate) struct DocProps<'a> { +pub(crate) struct DocProps { app: AppProps, - core: CoreProps<'a>, + core: CoreProps, } -impl<'a> DocProps<'a> { +impl DocProps { pub(crate) fn new(core_config: CorePropsConfig) -> DocProps { let app = AppProps::new(); let core = CoreProps::new(core_config); diff --git a/docx-core/src/documents/document.rs b/docx-core/src/documents/document.rs index e7e13bcce..a79d368a8 100644 --- a/docx-core/src/documents/document.rs +++ b/docx-core/src/documents/document.rs @@ -3,33 +3,33 @@ use crate::documents::BuildXML; use crate::xml_builder::*; #[derive(Debug)] -pub struct Document<'a> { - pub(crate) children: Vec>, +pub struct Document { + pub(crate) children: Vec, } #[derive(Debug, Clone)] -pub enum DocumentChild<'a> { - Paragraph(Paragraph<'a>), - Table(Table<'a>), +pub enum DocumentChild { + Paragraph(Paragraph), + Table(Table), } -impl<'a> Document<'a> { - pub fn new() -> Document<'a> { +impl Document { + pub fn new() -> Document { Default::default() } - pub fn add_paragraph(mut self, p: Paragraph<'a>) -> Self { + pub fn add_paragraph(mut self, p: Paragraph) -> Self { self.children.push(DocumentChild::Paragraph(p)); self } - pub fn add_table(mut self, t: Table<'a>) -> Self { + pub fn add_table(mut self, t: Table) -> Self { self.children.push(DocumentChild::Table(t)); self } } -impl<'a> Default for Document<'a> { +impl Default for Document { fn default() -> Self { Self { children: Vec::new(), @@ -37,7 +37,7 @@ impl<'a> Default for Document<'a> { } } -impl<'a> BuildXML for Document<'a> { +impl BuildXML for Document { fn build(&self) -> Vec { let mut b = XMLBuilder::new() .declaration(Some(true)) diff --git a/docx-core/src/documents/elements/bookmark_end.rs b/docx-core/src/documents/elements/bookmark_end.rs index d8ddeeb35..ffda2f3b5 100644 --- a/docx-core/src/documents/elements/bookmark_end.rs +++ b/docx-core/src/documents/elements/bookmark_end.rs @@ -2,17 +2,17 @@ use crate::documents::BuildXML; use crate::xml_builder::*; #[derive(Debug, Clone)] -pub struct BookmarkEnd<'a> { - id: &'a str, +pub struct BookmarkEnd { + id: String, } -impl<'a> BookmarkEnd<'a> { - pub fn new(id: &'a str) -> BookmarkEnd<'a> { - BookmarkEnd { id } +impl BookmarkEnd { + pub fn new(id: impl Into) -> BookmarkEnd { + BookmarkEnd { id: id.into() } } } -impl<'a> BuildXML for BookmarkEnd<'a> { +impl BuildXML for BookmarkEnd { fn build(&self) -> Vec { let b = XMLBuilder::new(); b.bookmark_end(&self.id).build() diff --git a/docx-core/src/documents/elements/bookmark_start.rs b/docx-core/src/documents/elements/bookmark_start.rs index dd14b0d55..caac7c0d3 100644 --- a/docx-core/src/documents/elements/bookmark_start.rs +++ b/docx-core/src/documents/elements/bookmark_start.rs @@ -2,18 +2,21 @@ use crate::documents::BuildXML; use crate::xml_builder::*; #[derive(Debug, Clone)] -pub struct BookmarkStart<'a> { - id: &'a str, - name: &'a str, +pub struct BookmarkStart { + id: String, + name: String, } -impl<'a> BookmarkStart<'a> { - pub fn new(id: &'a str, name: &'a str) -> BookmarkStart<'a> { - BookmarkStart { id, name } +impl BookmarkStart { + pub fn new(id: impl Into, name: impl Into) -> BookmarkStart { + BookmarkStart { + id: id.into(), + name: name.into(), + } } } -impl<'a> BuildXML for BookmarkStart<'a> { +impl BuildXML for BookmarkStart { fn build(&self) -> Vec { let b = XMLBuilder::new(); b.bookmark_start(&self.id, &self.name).build() diff --git a/docx-core/src/documents/elements/comment.rs b/docx-core/src/documents/elements/comment.rs index 7703e457c..98c5f9e90 100644 --- a/docx-core/src/documents/elements/comment.rs +++ b/docx-core/src/documents/elements/comment.rs @@ -2,56 +2,56 @@ use crate::documents::{BuildXML, Paragraph}; use crate::xml_builder::*; #[derive(Debug, Clone)] -pub struct Comment<'a> { - id: &'a str, - author: &'a str, - date: &'a str, - paragraph: Paragraph<'a>, +pub struct Comment { + id: String, + author: String, + date: String, + paragraph: Paragraph, } -impl<'a> Default for Comment<'a> { - fn default() -> Comment<'a> { +impl Default for Comment { + fn default() -> Comment { Comment { - id: "invalidId", - author: "unnamed", - date: "1970-01-01T00:00:00Z", + id: "invalidId".to_owned(), + author: "unnamed".to_owned(), + date: "1970-01-01T00:00:00Z".to_owned(), paragraph: Paragraph::new(), } } } -impl<'a> Comment<'a> { - pub fn new(id: &'a str) -> Comment<'a> { +impl Comment { + pub fn new(id: impl Into) -> Comment { Self { - id, + id: id.into(), ..Default::default() } } - pub fn author(mut self, author: &'a str) -> Comment<'a> { - self.author = author; + pub fn author(mut self, author: impl Into) -> Comment { + self.author = author.into(); self } - pub fn date(mut self, date: &'a str) -> Comment<'a> { - self.date = date; + pub fn date(mut self, date: impl Into) -> Comment { + self.date = date.into(); self } - pub fn paragraph(mut self, p: Paragraph<'a>) -> Comment<'a> { + pub fn paragraph(mut self, p: Paragraph) -> Comment { self.paragraph = p; self } - pub fn id(&self) -> &'a str { - self.id + pub fn id(&self) -> String { + self.id.clone() } } -impl<'a> BuildXML for Comment<'a> { +impl BuildXML for Comment { fn build(&self) -> Vec { XMLBuilder::new() - .open_comment(&self.id, self.author, self.date, "") + .open_comment(&self.id, &self.author, &self.date, "") .add_child(&self.paragraph) .close() .build() diff --git a/docx-core/src/documents/elements/comment_range_end.rs b/docx-core/src/documents/elements/comment_range_end.rs index 554b2beea..597273ccc 100644 --- a/docx-core/src/documents/elements/comment_range_end.rs +++ b/docx-core/src/documents/elements/comment_range_end.rs @@ -2,17 +2,17 @@ use crate::documents::BuildXML; use crate::xml_builder::*; #[derive(Debug, Clone)] -pub struct CommentRangeEnd<'a> { - id: &'a str, +pub struct CommentRangeEnd { + id: String, } -impl<'a> CommentRangeEnd<'a> { - pub fn new(id: &'a str) -> CommentRangeEnd<'a> { - CommentRangeEnd { id } +impl CommentRangeEnd { + pub fn new(id: impl Into) -> CommentRangeEnd { + CommentRangeEnd { id: id.into() } } } -impl<'a> BuildXML for CommentRangeEnd<'a> { +impl BuildXML for CommentRangeEnd { fn build(&self) -> Vec { let b = XMLBuilder::new(); b.open_run() diff --git a/docx-core/src/documents/elements/comment_range_start.rs b/docx-core/src/documents/elements/comment_range_start.rs index 3a37d163b..74020349b 100644 --- a/docx-core/src/documents/elements/comment_range_start.rs +++ b/docx-core/src/documents/elements/comment_range_start.rs @@ -3,25 +3,25 @@ use crate::documents::BuildXML; use crate::xml_builder::*; #[derive(Debug, Clone)] -pub struct CommentRangeStart<'a> { - id: &'a str, - comment: Comment<'a>, +pub struct CommentRangeStart { + id: String, + comment: Comment, } -impl<'a> CommentRangeStart<'a> { - pub fn new(comment: Comment<'a>) -> CommentRangeStart<'a> { +impl CommentRangeStart { + pub fn new(comment: Comment) -> CommentRangeStart { CommentRangeStart { id: comment.id(), comment, } } - pub(crate) fn comment(&self) -> Comment<'a> { + pub(crate) fn comment(&self) -> Comment { self.comment.clone() } } -impl<'a> BuildXML for CommentRangeStart<'a> { +impl BuildXML for CommentRangeStart { fn build(&self) -> Vec { let b = XMLBuilder::new(); b.comment_range_start(&self.id).build() diff --git a/docx-core/src/documents/elements/delete.rs b/docx-core/src/documents/elements/delete.rs index 4f55096c3..5dd75c36f 100644 --- a/docx-core/src/documents/elements/delete.rs +++ b/docx-core/src/documents/elements/delete.rs @@ -2,39 +2,39 @@ use crate::documents::{BuildXML, HistoryId, Run}; use crate::xml_builder::*; #[derive(Debug, Clone)] -pub struct Delete<'a> { - author: &'a str, - date: &'a str, - run: Run<'a>, +pub struct Delete { + author: String, + date: String, + run: Run, } -impl<'a> Default for Delete<'a> { - fn default() -> Delete<'a> { +impl Default for Delete { + fn default() -> Delete { Delete { - author: "unnamed", - date: "1970-01-01T00:00:00Z", + author: "unnamed".to_owned(), + date: "1970-01-01T00:00:00Z".to_owned(), run: Run::new(), } } } -impl<'a> Delete<'a> { - pub fn new() -> Delete<'a> { +impl Delete { + pub fn new() -> Delete { Default::default() } - pub fn run(mut self, run: Run<'a>) -> Delete<'a> { + pub fn run(mut self, run: Run) -> Delete { self.run = run; self } } -impl<'a> HistoryId for Delete<'a> {} +impl HistoryId for Delete {} -impl<'a> BuildXML for Delete<'a> { +impl BuildXML for Delete { fn build(&self) -> Vec { XMLBuilder::new() - .open_delete(&self.generate(), self.author, self.date) + .open_delete(&self.generate(), &self.author, &self.date) .add_child(&self.run) .close() .build() diff --git a/docx-core/src/documents/elements/insert.rs b/docx-core/src/documents/elements/insert.rs index 18480736e..4c3becdbe 100644 --- a/docx-core/src/documents/elements/insert.rs +++ b/docx-core/src/documents/elements/insert.rs @@ -2,39 +2,39 @@ use crate::documents::{BuildXML, HistoryId, Run}; use crate::xml_builder::*; #[derive(Debug, Clone)] -pub struct Insert<'a> { - author: &'a str, - date: &'a str, - run: Run<'a>, +pub struct Insert { + author: String, + date: String, + run: Run, } -impl<'a> Default for Insert<'a> { - fn default() -> Insert<'a> { +impl Default for Insert { + fn default() -> Insert { Insert { - author: "unnamed", - date: "1970-01-01T00:00:00Z", + author: "unnamed".to_owned(), + date: "1970-01-01T00:00:00Z".to_owned(), run: Run::new(), } } } -impl<'a> Insert<'a> { - pub fn new() -> Insert<'a> { +impl Insert { + pub fn new() -> Insert { Default::default() } - pub fn run(mut self, run: Run<'a>) -> Insert<'a> { + pub fn run(mut self, run: Run) -> Insert { self.run = run; self } } -impl<'a> HistoryId for Insert<'a> {} +impl HistoryId for Insert {} -impl<'a> BuildXML for Insert<'a> { +impl BuildXML for Insert { fn build(&self) -> Vec { XMLBuilder::new() - .open_insert(&self.generate(), self.author, self.date) + .open_insert(&self.generate(), &self.author, &self.date) .add_child(&self.run) .close() .build() diff --git a/docx-core/src/documents/elements/level.rs b/docx-core/src/documents/elements/level.rs index 414fbdf00..fcb238c76 100644 --- a/docx-core/src/documents/elements/level.rs +++ b/docx-core/src/documents/elements/level.rs @@ -3,23 +3,23 @@ use crate::types::*; use crate::xml_builder::*; #[derive(Debug, Clone)] -pub struct Level<'a> { +pub struct Level { level: usize, start: Start, - format: NumberFormat<'a>, - text: LevelText<'a>, - jc: LevelJc<'a>, + format: NumberFormat, + text: LevelText, + jc: LevelJc, paragraph_property: ParagraphProperty, } -impl<'a> Level<'a> { +impl Level { pub fn new( level: usize, start: Start, - format: NumberFormat<'a>, - text: LevelText<'a>, - jc: LevelJc<'a>, - ) -> Level<'a> { + format: NumberFormat, + text: LevelText, + jc: LevelJc, + ) -> Level { Self { level, start, @@ -36,7 +36,7 @@ impl<'a> Level<'a> { } } -impl<'a> BuildXML for Level<'a> { +impl BuildXML for Level { fn build(&self) -> Vec { XMLBuilder::new() .open_level(&format!("{}", self.level)) diff --git a/docx-core/src/documents/elements/level_jc.rs b/docx-core/src/documents/elements/level_jc.rs index 3de564fd2..14c20d5dd 100644 --- a/docx-core/src/documents/elements/level_jc.rs +++ b/docx-core/src/documents/elements/level_jc.rs @@ -2,20 +2,20 @@ use crate::documents::BuildXML; use crate::xml_builder::*; #[derive(Debug, Clone)] -pub struct LevelJc<'a> { - val: &'a str, +pub struct LevelJc { + val: String, } -impl<'a> LevelJc<'a> { - pub fn new(val: &'a str) -> Self { - Self { val } +impl LevelJc { + pub fn new(val: impl Into) -> Self { + Self { val: val.into() } } } -impl<'a> BuildXML for LevelJc<'a> { +impl BuildXML for LevelJc { fn build(&self) -> Vec { let b = XMLBuilder::new(); - b.level_justification(self.val).build() + b.level_justification(&self.val).build() } } diff --git a/docx-core/src/documents/elements/level_text.rs b/docx-core/src/documents/elements/level_text.rs index 425e6d0b3..da40304c3 100644 --- a/docx-core/src/documents/elements/level_text.rs +++ b/docx-core/src/documents/elements/level_text.rs @@ -2,20 +2,20 @@ use crate::documents::BuildXML; use crate::xml_builder::*; #[derive(Debug, Clone)] -pub struct LevelText<'a> { - val: &'a str, +pub struct LevelText { + val: String, } -impl<'a> LevelText<'a> { - pub fn new(val: &'a str) -> Self { - Self { val } +impl LevelText { + pub fn new(val: impl Into) -> Self { + Self { val: val.into() } } } -impl<'a> BuildXML for LevelText<'a> { +impl BuildXML for LevelText { fn build(&self) -> Vec { let b = XMLBuilder::new(); - b.level_text(self.val).build() + b.level_text(&self.val).build() } } diff --git a/docx-core/src/documents/elements/number_format.rs b/docx-core/src/documents/elements/number_format.rs index e1ebfbc61..53591098a 100644 --- a/docx-core/src/documents/elements/number_format.rs +++ b/docx-core/src/documents/elements/number_format.rs @@ -2,20 +2,20 @@ use crate::documents::BuildXML; use crate::xml_builder::*; #[derive(Debug, Clone)] -pub struct NumberFormat<'a> { - val: &'a str, +pub struct NumberFormat { + val: String, } -impl<'a> NumberFormat<'a> { - pub fn new(val: &'a str) -> Self { - Self { val } +impl NumberFormat { + pub fn new(val: impl Into) -> Self { + Self { val: val.into() } } } -impl<'a> BuildXML for NumberFormat<'a> { +impl BuildXML for NumberFormat { fn build(&self) -> Vec { let b = XMLBuilder::new(); - b.number_format(self.val).build() + b.number_format(&self.val).build() } } diff --git a/docx-core/src/documents/elements/numbering.rs b/docx-core/src/documents/elements/numbering.rs index 29a5c1159..415b0e247 100644 --- a/docx-core/src/documents/elements/numbering.rs +++ b/docx-core/src/documents/elements/numbering.rs @@ -2,34 +2,31 @@ use crate::documents::{BuildXML, Level}; use crate::xml_builder::*; #[derive(Debug, Clone)] -pub struct Numbering<'a> { - id: &'a str, - levels: Vec>, +pub struct Numbering { + id: usize, + levels: Vec, } -impl<'a> Numbering<'a> { - pub fn new(id: &'a str) -> Self { +impl Numbering { + pub fn new(id: usize) -> Self { Self { id, levels: vec![] } } - pub fn add_level(mut self, level: Level<'a>) -> Self { + pub fn add_level(mut self, level: Level) -> Self { self.levels.push(level); self } } -impl<'a> BuildXML for Numbering<'a> { +impl BuildXML for Numbering { fn build(&self) -> Vec { + let id = format!("{}", self.id); let mut b = XMLBuilder::new(); - b = b.open_abstract_num(self.id); + b = b.open_abstract_num(&id); for l in &self.levels { b = b.add_child(l); } - b.close() - .open_num(self.id) - .abstract_num_id(self.id) - .close() - .build() + b.close().open_num(&id).abstract_num_id(&id).close().build() } } @@ -44,7 +41,7 @@ mod tests { #[test] fn test_numbering() { - let mut c = Numbering::new("0"); + let mut c = Numbering::new(0); c = c.add_level(Level::new( 1, Start::new(1), diff --git a/docx-core/src/documents/elements/paragraph.rs b/docx-core/src/documents/elements/paragraph.rs index 41849c0e5..a74cc935a 100644 --- a/docx-core/src/documents/elements/paragraph.rs +++ b/docx-core/src/documents/elements/paragraph.rs @@ -4,13 +4,13 @@ use crate::types::*; use crate::xml_builder::*; #[derive(Debug, Clone)] -pub struct Paragraph<'a> { - pub(crate) children: Vec>, +pub struct Paragraph { + pub(crate) children: Vec, property: ParagraphProperty, attrs: Vec<(String, String)>, } -impl<'a> Default for Paragraph<'a> { +impl Default for Paragraph { fn default() -> Self { Self { children: Vec::new(), @@ -21,17 +21,17 @@ impl<'a> Default for Paragraph<'a> { } #[derive(Debug, Clone)] -pub enum ParagraphChild<'a> { - Run(Run<'a>), - Insert(Insert<'a>), - Delete(Delete<'a>), - BookmarkStart(BookmarkStart<'a>), - BookmarkEnd(BookmarkEnd<'a>), - CommentStart(CommentRangeStart<'a>), - CommentEnd(CommentRangeEnd<'a>), +pub enum ParagraphChild { + Run(Run), + Insert(Insert), + Delete(Delete), + BookmarkStart(BookmarkStart), + BookmarkEnd(BookmarkEnd), + CommentStart(CommentRangeStart), + CommentEnd(CommentRangeEnd), } -impl<'a> BuildXML for ParagraphChild<'a> { +impl BuildXML for ParagraphChild { fn build(&self) -> Vec { match self { ParagraphChild::Run(v) => v.build(), @@ -45,8 +45,8 @@ impl<'a> BuildXML for ParagraphChild<'a> { } } -impl<'a> Paragraph<'a> { - pub fn new() -> Paragraph<'a> { +impl Paragraph { + pub fn new() -> Paragraph { Default::default() } @@ -54,39 +54,43 @@ impl<'a> Paragraph<'a> { &self.children } - pub fn add_run(mut self, run: Run<'a>) -> Paragraph<'a> { + pub fn add_run(mut self, run: Run) -> Paragraph { self.children.push(ParagraphChild::Run(run)); self } - pub fn add_insert(mut self, insert: Insert<'a>) -> Paragraph<'a> { + pub fn add_insert(mut self, insert: Insert) -> Paragraph { self.children.push(ParagraphChild::Insert(insert)); self } - pub fn add_delete(mut self, delete: Delete<'a>) -> Paragraph<'a> { + pub fn add_delete(mut self, delete: Delete) -> Paragraph { self.children.push(ParagraphChild::Delete(delete)); self } - pub fn add_attr(mut self, key: impl Into, val: impl Into) -> Paragraph<'a> { + pub fn add_attr(mut self, key: impl Into, val: impl Into) -> Paragraph { self.attrs.push((key.into(), val.into())); self } - pub fn add_bookmark_start(mut self, id: &'a str, name: &'a str) -> Paragraph<'a> { + pub fn add_bookmark_start( + mut self, + id: impl Into, + name: impl Into, + ) -> Paragraph { self.children .push(ParagraphChild::BookmarkStart(BookmarkStart::new(id, name))); self } - pub fn add_bookmark_end(mut self, id: &'a str) -> Paragraph<'a> { + pub fn add_bookmark_end(mut self, id: impl Into) -> Paragraph { self.children .push(ParagraphChild::BookmarkEnd(BookmarkEnd::new(id))); self } - pub fn add_comment_start(mut self, comment: Comment<'a>) -> Paragraph<'a> { + pub fn add_comment_start(mut self, comment: Comment) -> Paragraph { self.children .push(ParagraphChild::CommentStart(CommentRangeStart::new( comment, @@ -94,33 +98,29 @@ impl<'a> Paragraph<'a> { self } - pub fn add_comment_end(mut self, id: &'a str) -> Paragraph<'a> { + pub fn add_comment_end(mut self, id: impl Into) -> Paragraph { self.children .push(ParagraphChild::CommentEnd(CommentRangeEnd::new(id))); self } - pub fn align(mut self, alignment_type: AlignmentType) -> Paragraph<'a> { + pub fn align(mut self, alignment_type: AlignmentType) -> Paragraph { self.property = self.property.align(alignment_type); self } - pub fn style(mut self, style_id: &str) -> Paragraph<'a> { + pub fn style(mut self, style_id: &str) -> Paragraph { self.property = self.property.style(style_id); self } - pub fn indent( - mut self, - left: usize, - special_indent: Option, - ) -> Paragraph<'a> { + pub fn indent(mut self, left: usize, special_indent: Option) -> Paragraph { self.property = self.property.indent(left, special_indent); self } } -impl<'a> BuildXML for Paragraph<'a> { +impl BuildXML for Paragraph { fn build(&self) -> Vec { XMLBuilder::new() .open_paragraph(&self.attrs) diff --git a/docx-core/src/documents/elements/paragraph_property.rs b/docx-core/src/documents/elements/paragraph_property.rs index b00b94ab5..502b8a654 100644 --- a/docx-core/src/documents/elements/paragraph_property.rs +++ b/docx-core/src/documents/elements/paragraph_property.rs @@ -1,4 +1,4 @@ -use super::{Indent, Justification, ParagraphStyle, RunProperty}; +use super::*; use crate::documents::BuildXML; use crate::types::{AlignmentType, SpecialIndentType}; use crate::xml_builder::*; diff --git a/docx-core/src/documents/elements/run.rs b/docx-core/src/documents/elements/run.rs index 09c4c20e5..38d8277e2 100644 --- a/docx-core/src/documents/elements/run.rs +++ b/docx-core/src/documents/elements/run.rs @@ -4,12 +4,12 @@ use crate::types::BreakType; use crate::xml_builder::*; #[derive(Debug, Clone)] -pub struct Run<'a> { +pub struct Run { run_property: RunProperty, - children: Vec>, + children: Vec, } -impl<'a> Default for Run<'a> { +impl Default for Run { fn default() -> Self { let run_property = RunProperty::new(); Self { @@ -20,72 +20,72 @@ impl<'a> Default for Run<'a> { } #[derive(Debug, Clone)] -pub enum RunChild<'a> { - Text(Text<'a>), +pub enum RunChild { + Text(Text), DeleteText(DeleteText), Tab(Tab), Break(Break), } -impl<'a> Run<'a> { - pub fn new() -> Run<'a> { +impl Run { + pub fn new() -> Run { Run { ..Default::default() } } - pub fn add_text(mut self, text: &'a str) -> Run<'a> { + pub fn add_text(mut self, text: impl Into) -> Run { self.children.push(RunChild::Text(Text::new(text))); self } - pub fn add_delete_text(mut self, text: &'a str) -> Run<'a> { + pub fn add_delete_text(mut self, text: impl Into) -> Run { self.children.push(RunChild::Text(Text::new(text))); self } - pub fn add_tab(mut self) -> Run<'a> { + pub fn add_tab(mut self) -> Run { self.children.push(RunChild::Tab(Tab::new())); self } - pub fn add_break(mut self, break_type: BreakType) -> Run<'a> { + pub fn add_break(mut self, break_type: BreakType) -> Run { self.children.push(RunChild::Break(Break::new(break_type))); self } - pub fn size(mut self, size: usize) -> Run<'a> { + pub fn size(mut self, size: usize) -> Run { self.run_property = self.run_property.size(size); self } - pub fn color(mut self, color: &'a str) -> Run<'a> { + pub fn color(mut self, color: impl Into) -> Run { self.run_property = self.run_property.color(color); self } - pub fn highlight(mut self, color: &'a str) -> Run<'a> { + pub fn highlight(mut self, color: impl Into) -> Run { self.run_property = self.run_property.highlight(color); self } - pub fn bold(mut self) -> Run<'a> { + pub fn bold(mut self) -> Run { self.run_property = self.run_property.bold(); self } - pub fn italic(mut self) -> Run<'a> { + pub fn italic(mut self) -> Run { self.run_property = self.run_property.italic(); self } - pub fn underline(mut self, line_type: &'a str) -> Run<'a> { + pub fn underline(mut self, line_type: impl Into) -> Run { self.run_property = self.run_property.underline(line_type); self } } -impl<'a> BuildXML for Run<'a> { +impl BuildXML for Run { fn build(&self) -> Vec { let b = XMLBuilder::new(); let mut b = b.open_run().add_child(&self.run_property); diff --git a/docx-core/src/documents/elements/run_property.rs b/docx-core/src/documents/elements/run_property.rs index 0c01b8ff4..602ebf9cb 100644 --- a/docx-core/src/documents/elements/run_property.rs +++ b/docx-core/src/documents/elements/run_property.rs @@ -26,12 +26,12 @@ impl RunProperty { self } - pub fn color(mut self, color: &str) -> RunProperty { + pub fn color(mut self, color: impl Into) -> RunProperty { self.color = Some(Color::new(color)); self } - pub fn highlight(mut self, color: &str) -> RunProperty { + pub fn highlight(mut self, color: impl Into) -> RunProperty { self.highlight = Some(Highlight::new(color)); self } @@ -48,7 +48,7 @@ impl RunProperty { self } - pub fn underline(mut self, line_type: &str) -> RunProperty { + pub fn underline(mut self, line_type: impl Into) -> RunProperty { self.underline = Some(Underline::new(line_type)); self } diff --git a/docx-core/src/documents/elements/table.rs b/docx-core/src/documents/elements/table.rs index efd2376d3..54cded0ad 100644 --- a/docx-core/src/documents/elements/table.rs +++ b/docx-core/src/documents/elements/table.rs @@ -3,14 +3,14 @@ use crate::documents::BuildXML; use crate::xml_builder::*; #[derive(Debug, Clone)] -pub struct Table<'a> { - pub(crate) rows: Vec>, +pub struct Table { + pub(crate) rows: Vec, property: TableProperty, grid: Vec, } -impl<'a> Table<'a> { - pub fn new(rows: Vec>) -> Table<'a> { +impl Table { + pub fn new(rows: Vec) -> Table { let property = TableProperty::new(); let grid = vec![]; Self { @@ -20,13 +20,13 @@ impl<'a> Table<'a> { } } - pub fn set_grid(mut self, grid: Vec) -> Table<'a> { + pub fn set_grid(mut self, grid: Vec) -> Table { self.grid = grid; self } } -impl<'a> BuildXML for Table<'a> { +impl BuildXML for Table { fn build(&self) -> Vec { let grid = TableGrid::new(self.grid.clone()); let b = XMLBuilder::new() diff --git a/docx-core/src/documents/elements/table_cell.rs b/docx-core/src/documents/elements/table_cell.rs index ccf93b00f..534d5ba30 100644 --- a/docx-core/src/documents/elements/table_cell.rs +++ b/docx-core/src/documents/elements/table_cell.rs @@ -4,40 +4,40 @@ use crate::types::*; use crate::xml_builder::*; #[derive(Debug, Clone)] -pub struct TableCell<'a> { - pub(crate) contents: Vec>, +pub struct TableCell { + pub(crate) contents: Vec, property: TableCellProperty, } #[derive(Debug, Clone)] -pub enum TableCellContent<'a> { - Paragraph(Paragraph<'a>), +pub enum TableCellContent { + Paragraph(Paragraph), } -impl<'a> TableCell<'a> { - pub fn new() -> TableCell<'a> { +impl TableCell { + pub fn new() -> TableCell { let property = TableCellProperty::new(); let contents = vec![]; Self { property, contents } } - pub fn add_paragraph(mut self, p: Paragraph<'a>) -> TableCell<'a> { + pub fn add_paragraph(mut self, p: Paragraph) -> TableCell { self.contents.push(TableCellContent::Paragraph(p)); self } - pub fn vertical_merge(mut self, t: VMergeType) -> TableCell<'a> { + pub fn vertical_merge(mut self, t: VMergeType) -> TableCell { self.property = self.property.vertical_merge(t); self } - pub fn grid_span(mut self, v: usize) -> TableCell<'a> { + pub fn grid_span(mut self, v: usize) -> TableCell { self.property = self.property.grid_span(v); self } } -impl<'a> BuildXML for TableCell<'a> { +impl BuildXML for TableCell { fn build(&self) -> Vec { let b = XMLBuilder::new(); let mut b = b.open_table_cell().add_child(&self.property); diff --git a/docx-core/src/documents/elements/table_row.rs b/docx-core/src/documents/elements/table_row.rs index 87fde2f82..b3dff7f48 100644 --- a/docx-core/src/documents/elements/table_row.rs +++ b/docx-core/src/documents/elements/table_row.rs @@ -3,19 +3,19 @@ use crate::documents::BuildXML; use crate::xml_builder::*; #[derive(Debug, Clone)] -pub struct TableRow<'a> { - pub(crate) cells: Vec>, +pub struct TableRow { + pub(crate) cells: Vec, property: TableRowProperty, } -impl<'a> TableRow<'a> { - pub fn new(cells: Vec>) -> TableRow<'a> { +impl TableRow { + pub fn new(cells: Vec) -> TableRow { let property = TableRowProperty::new(); Self { property, cells } } } -impl<'a> BuildXML for TableRow<'a> { +impl BuildXML for TableRow { fn build(&self) -> Vec { let b = XMLBuilder::new() .open_table_row() diff --git a/docx-core/src/documents/elements/text.rs b/docx-core/src/documents/elements/text.rs index 4c6ac2d94..65e0ad6b1 100644 --- a/docx-core/src/documents/elements/text.rs +++ b/docx-core/src/documents/elements/text.rs @@ -2,13 +2,13 @@ use crate::documents::BuildXML; use crate::xml_builder::*; #[derive(Debug, Clone)] -pub struct Text<'a> { - text: &'a str, +pub struct Text { + text: String, preserve_space: bool, } -impl<'a> Text<'a> { - pub fn new(text: &'a str) -> Text { +impl Text { + pub fn new(text: impl Into) -> Text { Text { text: text.into(), preserve_space: true, @@ -16,7 +16,7 @@ impl<'a> Text<'a> { } } -impl<'a> BuildXML for Text<'a> { +impl BuildXML for Text { fn build(&self) -> Vec { XMLBuilder::new().text(&self.text, true).build() } diff --git a/docx-core/src/documents/mod.rs b/docx-core/src/documents/mod.rs index 6c029f116..0c6a02db8 100644 --- a/docx-core/src/documents/mod.rs +++ b/docx-core/src/documents/mod.rs @@ -30,19 +30,20 @@ pub use styles::*; pub use xml_docx::*; #[derive(Debug)] -pub struct Docx<'a> { +pub struct Docx { content_type: ContentTypes, rels: Rels, document_rels: DocumentRels, - doc_props: DocProps<'a>, + doc_props: DocProps, styles: Styles, - document: Document<'a>, - comments: Comments<'a>, + document: Document, + comments: Comments, + numberings: Numberings, settings: Settings, font_table: FontTable, } -impl<'a> Default for Docx<'a> { +impl Default for Docx { fn default() -> Self { let content_type = ContentTypes::new(); let rels = Rels::new(); @@ -53,6 +54,7 @@ impl<'a> Default for Docx<'a> { let settings = Settings::new(); let font_table = FontTable::new(); let comments = Comments::new(); + let numberings = Numberings::new(); Docx { content_type, rels, @@ -63,25 +65,31 @@ impl<'a> Default for Docx<'a> { document_rels, settings, font_table, + numberings, } } } -impl<'a> Docx<'a> { - pub fn new() -> Docx<'a> { +impl Docx { + pub fn new() -> Docx { Default::default() } - pub fn add_paragraph(mut self, p: Paragraph<'a>) -> Docx<'a> { + pub fn add_paragraph(mut self, p: Paragraph) -> Docx { self.document = self.document.add_paragraph(p); self } - pub fn add_table(mut self, t: Table<'a>) -> Docx<'a> { + pub fn add_table(mut self, t: Table) -> Docx { self.document = self.document.add_table(t); self } + pub fn add_numbering(mut self, num: Numbering) -> Docx { + self.numberings = self.numberings.add_numbering(num); + self + } + pub fn build(&mut self) -> XMLDocx { self.update_comments(); XMLDocx { @@ -94,12 +102,13 @@ impl<'a> Docx<'a> { document_rels: self.document_rels.build(), settings: self.settings.build(), font_table: self.font_table.build(), + numberings: self.numberings.build(), } } // Traverse and clone comments from document and add to comments node. fn update_comments(&mut self) { - let mut comments: Vec> = vec![]; + let mut comments: Vec = vec![]; for child in &self.document.children { match child { DocumentChild::Paragraph(paragraph) => { diff --git a/docx-core/src/documents/numberings.rs b/docx-core/src/documents/numberings.rs index 14a26b86d..2485955c8 100644 --- a/docx-core/src/documents/numberings.rs +++ b/docx-core/src/documents/numberings.rs @@ -4,49 +4,128 @@ use crate::types::*; use crate::xml_builder::*; #[derive(Debug)] -pub struct Numberings {} +pub struct Numberings { + numberings: Vec, +} impl Numberings { pub fn new() -> Self { Default::default() } + + pub fn add_numbering(mut self, n: Numbering) -> Self { + self.numberings.push(n); + self + } } impl Default for Numberings { fn default() -> Self { - Self {} + Self { numberings: vec![] } } } impl BuildXML for Numberings { fn build(&self) -> Vec { let mut b = XMLBuilder::new().declaration(Some(true)).open_numbering(); - b = add_default_numbering(b); + b = b.add_child(&create_default_numbering()); + for n in &self.numberings { + b = b.add_child(n); + } b.close().build() } } -fn add_default_numbering(b: XMLBuilder) -> XMLBuilder { - let mut b = b.open_abstract_num("0"); - b = b.add_child( - &Level::new( - 0, - Start::new(1), - NumberFormat::new("decimal"), - LevelText::new("%1."), - LevelJc::new("left"), - ) - .indent(420, Some(SpecialIndentType::Hanging(420))), - ); - b = b.add_child( - &Level::new( - 1, - Start::new(1), - NumberFormat::new("decimal"), - LevelText::new("%2."), - LevelJc::new("left"), - ) - .indent(840, Some(SpecialIndentType::Hanging(420))), - ); - b.close() +fn create_default_numbering() -> Numbering { + Numbering::new(0) + .add_level( + Level::new( + 0, + Start::new(1), + NumberFormat::new("decimal"), + LevelText::new("%1."), + LevelJc::new("left"), + ) + .indent(420, Some(SpecialIndentType::Hanging(420))), + ) + .add_level( + Level::new( + 1, + Start::new(1), + NumberFormat::new("decimal"), + LevelText::new("(%2)"), + LevelJc::new("left"), + ) + .indent(840, Some(SpecialIndentType::Hanging(420))), + ) + .add_level( + Level::new( + 2, + Start::new(1), + NumberFormat::new("decimalEnclosedCircle"), + LevelText::new("%3"), + LevelJc::new("left"), + ) + .indent(1260, Some(SpecialIndentType::Hanging(420))), + ) + .add_level( + Level::new( + 3, + Start::new(1), + NumberFormat::new("decimal"), + LevelText::new("%4."), + LevelJc::new("left"), + ) + .indent(1680, Some(SpecialIndentType::Hanging(420))), + ) + .add_level( + Level::new( + 4, + Start::new(1), + NumberFormat::new("decimal"), + LevelText::new("(%5)"), + LevelJc::new("left"), + ) + .indent(2100, Some(SpecialIndentType::Hanging(420))), + ) + .add_level( + Level::new( + 5, + Start::new(1), + NumberFormat::new("decimalEnclosedCircle"), + LevelText::new("%6"), + LevelJc::new("left"), + ) + .indent(2520, Some(SpecialIndentType::Hanging(420))), + ) + .add_level( + Level::new( + 6, + Start::new(1), + NumberFormat::new("decimal"), + LevelText::new("%7."), + LevelJc::new("left"), + ) + .indent(2940, Some(SpecialIndentType::Hanging(420))), + ) + .add_level( + Level::new( + 7, + Start::new(1), + NumberFormat::new("decimal"), + LevelText::new("(%8)"), + LevelJc::new("left"), + ) + .indent(3360, Some(SpecialIndentType::Hanging(420))), + ) + .add_level( + Level::new( + 8, + Start::new(1), + NumberFormat::new("decimalEnclosedCircle"), + LevelText::new("%9"), + LevelJc::new("left"), + ) + .indent(3780, Some(SpecialIndentType::Hanging(420))), + ) } diff --git a/docx-core/src/documents/xml_docx.rs b/docx-core/src/documents/xml_docx.rs index d7fb08279..41e1002ea 100644 --- a/docx-core/src/documents/xml_docx.rs +++ b/docx-core/src/documents/xml_docx.rs @@ -15,6 +15,7 @@ pub struct XMLDocx { pub document_rels: Vec, pub settings: Vec, pub font_table: Vec, + pub numberings: Vec, } impl XMLDocx { diff --git a/docx-wasm/index.js b/docx-wasm/index.js index 1473d5757..e122e3d86 100644 --- a/docx-wasm/index.js +++ b/docx-wasm/index.js @@ -6,7 +6,11 @@ const rust = import("./pkg"); rust .then(m => { - let docx = m.createDocx().add_paragraph(); + const p = m + .createParagraph() + .add_run(m.createRun().add_text("Hello World!!")); + let docx = m.createDocx().add_paragraph(p); saveAs(new Blob([docx.build()]), "example.docx"); + docx.free(); }) .catch(console.error); diff --git a/docx-wasm/src/lib.rs b/docx-wasm/src/lib.rs index d94d491ae..08856596a 100644 --- a/docx-wasm/src/lib.rs +++ b/docx-wasm/src/lib.rs @@ -3,20 +3,17 @@ use wasm_bindgen::prelude::*; #[wasm_bindgen] #[derive(Debug)] -pub struct Docx(docx_core::Docx<'static>); +pub struct Docx(docx_core::Docx); -#[wasm_bindgen] -#[allow(non_snake_case)] -pub fn createDocx() -> Docx { +#[wasm_bindgen(js_name = createDocx)] +pub fn create_docx() -> Docx { Docx(docx_core::Docx::new()) } #[wasm_bindgen] impl Docx { - pub fn add_paragraph(mut self) -> Self { - self.0 = self.0.add_paragraph( - docx_core::Paragraph::new().add_run(docx_core::Run::new().add_text("Hello")), - ); + pub fn add_paragraph(mut self, p: Paragraph) -> Self { + self.0 = self.0.add_paragraph(p.0); self } @@ -29,8 +26,38 @@ impl Docx { } Ok(cur.into_inner()) } +} + +#[wasm_bindgen] +#[derive(Debug)] +pub struct Paragraph(docx_core::Paragraph); - pub fn test(&self, t: docx_core::StyleType) { - () +#[wasm_bindgen(js_name = createParagraph)] +pub fn create_paragraph() -> Paragraph { + Paragraph(docx_core::Paragraph::new()) +} + +#[wasm_bindgen] +impl Paragraph { + pub fn add_run(mut self, run: Run) -> Self { + self.0 = self.0.add_run(run.0); + self + } +} + +#[wasm_bindgen] +#[derive(Debug)] +pub struct Run(docx_core::Run); + +#[wasm_bindgen(js_name = createRun)] +pub fn create_run() -> Run { + Run(docx_core::Run::new()) +} + +#[wasm_bindgen] +impl Run { + pub fn add_text(mut self, text: &str) -> Self { + self.0 = self.0.add_text(text); + self } }