Use string for wasm (#1)

* feat: Add numberings

* 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
main
bokuweb 2019-12-09 04:14:27 +09:00 committed by GitHub
parent 182f82e9a0
commit 73001dc720
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 339 additions and 278 deletions

View File

@ -3,26 +3,26 @@ use crate::documents::BuildXML;
use crate::xml_builder::*; use crate::xml_builder::*;
#[derive(Debug)] #[derive(Debug)]
pub struct Comments<'a> { pub struct Comments {
comments: Vec<Comment<'a>>, comments: Vec<Comment>,
} }
impl<'a> Comments<'a> { impl Comments {
pub fn new() -> Self { pub fn new() -> Self {
Default::default() Default::default()
} }
pub(crate) fn add_comments(&mut self, comments: Vec<Comment<'a>>) { pub(crate) fn add_comments(&mut self, comments: Vec<Comment>) {
self.comments = comments; self.comments = comments;
} }
} }
impl<'a> Default for Comments<'a> { impl Default for Comments {
fn default() -> Self { fn default() -> Self {
Self { comments: vec![] } Self { comments: vec![] }
} }
} }
impl<'a> BuildXML for Comments<'a> { impl BuildXML for Comments {
fn build(&self) -> Vec<u8> { fn build(&self) -> Vec<u8> {
let mut b = XMLBuilder::new().declaration(Some(true)).open_comments(); let mut b = XMLBuilder::new().declaration(Some(true)).open_comments();
for c in &self.comments { for c in &self.comments {

View File

@ -2,30 +2,30 @@ use crate::documents::BuildXML;
use crate::xml_builder::*; use crate::xml_builder::*;
#[derive(Debug)] #[derive(Debug)]
pub struct CoreProps<'a> { pub struct CoreProps {
config: CorePropsConfig<'a>, config: CorePropsConfig,
} }
#[derive(Debug)] #[derive(Debug)]
pub struct CorePropsConfig<'a> { pub struct CorePropsConfig {
created: Option<&'a str>, created: Option<String>,
creator: Option<&'a str>, creator: Option<String>,
description: Option<&'a str>, description: Option<String>,
language: Option<&'a str>, language: Option<String>,
last_modified_by: Option<&'a str>, last_modified_by: Option<String>,
modified: Option<&'a str>, modified: Option<String>,
revision: Option<usize>, revision: Option<usize>,
subject: Option<&'a str>, subject: Option<String>,
title: Option<&'a str>, title: Option<String>,
} }
impl<'a> CoreProps<'a> { impl CoreProps {
pub(crate) fn new(config: CorePropsConfig<'a>) -> CoreProps { pub(crate) fn new(config: CorePropsConfig) -> CoreProps {
CoreProps { config } CoreProps { config }
} }
} }
impl<'a> CorePropsConfig<'a> { impl CorePropsConfig {
pub fn new() -> Self { pub fn new() -> Self {
CorePropsConfig { CorePropsConfig {
created: None, created: None,
@ -41,7 +41,7 @@ impl<'a> CorePropsConfig<'a> {
} }
} }
impl<'a> BuildXML for CoreProps<'a> { impl BuildXML for CoreProps {
fn build(&self) -> Vec<u8> { fn build(&self) -> Vec<u8> {
let b = XMLBuilder::new(); let b = XMLBuilder::new();
let base = b.declaration(Some(true)).open_core_properties( let base = b.declaration(Some(true)).open_core_properties(
@ -58,32 +58,40 @@ impl<'a> BuildXML for CoreProps<'a> {
"dcterms:W3CDTF", "dcterms:W3CDTF",
self.config self.config
.created .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( .cp_last_modified_by(
self.config self.config
.last_modified_by .last_modified_by
.map_or_else(|| "unknown", |v| v), .as_ref()
.map_or_else(|| "unknown", |v| &v),
) )
.dcterms_modified( .dcterms_modified(
"dcterms:W3CDTF", "dcterms:W3CDTF",
self.config self.config
.modified .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)); .cp_revision(&self.config.revision.map_or_else(|| "1".to_owned(), convert));
if let Some(v) = self.config.description { if let Some(v) = self.config.description.as_ref() {
base = base.dc_description(v); base = base.dc_description(&v);
} }
if let Some(v) = self.config.language { if let Some(v) = self.config.language.as_ref() {
base = base.dc_language(v); base = base.dc_language(&v);
} }
if let Some(v) = self.config.subject { if let Some(v) = self.config.subject.as_ref() {
base = base.dc_subject(v); base = base.dc_subject(&v);
} }
if let Some(v) = self.config.title { if let Some(v) = self.config.title.as_ref() {
base = base.dc_title(v); base = base.dc_title(&v);
} }
base.close().build() base.close().build()
} }
@ -127,15 +135,15 @@ mod tests {
#[test] #[test]
fn test_configured_doc_props_core_build() { fn test_configured_doc_props_core_build() {
let c = CoreProps::new(CorePropsConfig { let c = CoreProps::new(CorePropsConfig {
created: Some("2019-01-01"), created: Some("2019-01-01".to_owned()),
creator: Some("foo"), creator: Some("foo".to_owned()),
description: Some("bar"), description: Some("bar".to_owned()),
language: Some("en"), language: Some("en".to_owned()),
last_modified_by: Some("go"), last_modified_by: Some("go".to_owned()),
modified: Some("2019-01-01"), modified: Some("2019-01-01".to_owned()),
revision: Some(1), revision: Some(1),
subject: Some("subject"), subject: Some("subject".to_owned()),
title: Some("title"), title: Some("title".to_owned()),
}); });
let b = c.build(); let b = c.build();
assert_eq!( assert_eq!(

View File

@ -6,12 +6,12 @@ pub use self::core::*;
use crate::documents::BuildXML; use crate::documents::BuildXML;
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct DocProps<'a> { pub(crate) struct DocProps {
app: AppProps, app: AppProps,
core: CoreProps<'a>, core: CoreProps,
} }
impl<'a> DocProps<'a> { impl DocProps {
pub(crate) fn new(core_config: CorePropsConfig) -> DocProps { pub(crate) fn new(core_config: CorePropsConfig) -> DocProps {
let app = AppProps::new(); let app = AppProps::new();
let core = CoreProps::new(core_config); let core = CoreProps::new(core_config);

View File

@ -3,33 +3,33 @@ use crate::documents::BuildXML;
use crate::xml_builder::*; use crate::xml_builder::*;
#[derive(Debug)] #[derive(Debug)]
pub struct Document<'a> { pub struct Document {
pub(crate) children: Vec<DocumentChild<'a>>, pub(crate) children: Vec<DocumentChild>,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum DocumentChild<'a> { pub enum DocumentChild {
Paragraph(Paragraph<'a>), Paragraph(Paragraph),
Table(Table<'a>), Table(Table),
} }
impl<'a> Document<'a> { impl Document {
pub fn new() -> Document<'a> { pub fn new() -> Document {
Default::default() 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.children.push(DocumentChild::Paragraph(p));
self 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.children.push(DocumentChild::Table(t));
self self
} }
} }
impl<'a> Default for Document<'a> { impl Default for Document {
fn default() -> Self { fn default() -> Self {
Self { Self {
children: Vec::new(), 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<u8> { fn build(&self) -> Vec<u8> {
let mut b = XMLBuilder::new() let mut b = XMLBuilder::new()
.declaration(Some(true)) .declaration(Some(true))

View File

@ -2,17 +2,17 @@ use crate::documents::BuildXML;
use crate::xml_builder::*; use crate::xml_builder::*;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct BookmarkEnd<'a> { pub struct BookmarkEnd {
id: &'a str, id: String,
} }
impl<'a> BookmarkEnd<'a> { impl BookmarkEnd {
pub fn new(id: &'a str) -> BookmarkEnd<'a> { pub fn new(id: impl Into<String>) -> BookmarkEnd {
BookmarkEnd { id } BookmarkEnd { id: id.into() }
} }
} }
impl<'a> BuildXML for BookmarkEnd<'a> { impl BuildXML for BookmarkEnd {
fn build(&self) -> Vec<u8> { fn build(&self) -> Vec<u8> {
let b = XMLBuilder::new(); let b = XMLBuilder::new();
b.bookmark_end(&self.id).build() b.bookmark_end(&self.id).build()

View File

@ -2,18 +2,21 @@ use crate::documents::BuildXML;
use crate::xml_builder::*; use crate::xml_builder::*;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct BookmarkStart<'a> { pub struct BookmarkStart {
id: &'a str, id: String,
name: &'a str, name: String,
} }
impl<'a> BookmarkStart<'a> { impl BookmarkStart {
pub fn new(id: &'a str, name: &'a str) -> BookmarkStart<'a> { pub fn new(id: impl Into<String>, name: impl Into<String>) -> BookmarkStart {
BookmarkStart { id, name } BookmarkStart {
id: id.into(),
name: name.into(),
}
} }
} }
impl<'a> BuildXML for BookmarkStart<'a> { impl BuildXML for BookmarkStart {
fn build(&self) -> Vec<u8> { fn build(&self) -> Vec<u8> {
let b = XMLBuilder::new(); let b = XMLBuilder::new();
b.bookmark_start(&self.id, &self.name).build() b.bookmark_start(&self.id, &self.name).build()

View File

@ -2,56 +2,56 @@ use crate::documents::{BuildXML, Paragraph};
use crate::xml_builder::*; use crate::xml_builder::*;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Comment<'a> { pub struct Comment {
id: &'a str, id: String,
author: &'a str, author: String,
date: &'a str, date: String,
paragraph: Paragraph<'a>, paragraph: Paragraph,
} }
impl<'a> Default for Comment<'a> { impl Default for Comment {
fn default() -> Comment<'a> { fn default() -> Comment {
Comment { Comment {
id: "invalidId", id: "invalidId".to_owned(),
author: "unnamed", author: "unnamed".to_owned(),
date: "1970-01-01T00:00:00Z", date: "1970-01-01T00:00:00Z".to_owned(),
paragraph: Paragraph::new(), paragraph: Paragraph::new(),
} }
} }
} }
impl<'a> Comment<'a> { impl Comment {
pub fn new(id: &'a str) -> Comment<'a> { pub fn new(id: impl Into<String>) -> Comment {
Self { Self {
id, id: id.into(),
..Default::default() ..Default::default()
} }
} }
pub fn author(mut self, author: &'a str) -> Comment<'a> { pub fn author(mut self, author: impl Into<String>) -> Comment {
self.author = author; self.author = author.into();
self self
} }
pub fn date(mut self, date: &'a str) -> Comment<'a> { pub fn date(mut self, date: impl Into<String>) -> Comment {
self.date = date; self.date = date.into();
self self
} }
pub fn paragraph(mut self, p: Paragraph<'a>) -> Comment<'a> { pub fn paragraph(mut self, p: Paragraph) -> Comment {
self.paragraph = p; self.paragraph = p;
self self
} }
pub fn id(&self) -> &'a str { pub fn id(&self) -> String {
self.id self.id.clone()
} }
} }
impl<'a> BuildXML for Comment<'a> { impl BuildXML for Comment {
fn build(&self) -> Vec<u8> { fn build(&self) -> Vec<u8> {
XMLBuilder::new() XMLBuilder::new()
.open_comment(&self.id, self.author, self.date, "") .open_comment(&self.id, &self.author, &self.date, "")
.add_child(&self.paragraph) .add_child(&self.paragraph)
.close() .close()
.build() .build()

View File

@ -2,17 +2,17 @@ use crate::documents::BuildXML;
use crate::xml_builder::*; use crate::xml_builder::*;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct CommentRangeEnd<'a> { pub struct CommentRangeEnd {
id: &'a str, id: String,
} }
impl<'a> CommentRangeEnd<'a> { impl CommentRangeEnd {
pub fn new(id: &'a str) -> CommentRangeEnd<'a> { pub fn new(id: impl Into<String>) -> CommentRangeEnd {
CommentRangeEnd { id } CommentRangeEnd { id: id.into() }
} }
} }
impl<'a> BuildXML for CommentRangeEnd<'a> { impl BuildXML for CommentRangeEnd {
fn build(&self) -> Vec<u8> { fn build(&self) -> Vec<u8> {
let b = XMLBuilder::new(); let b = XMLBuilder::new();
b.open_run() b.open_run()

View File

@ -3,25 +3,25 @@ use crate::documents::BuildXML;
use crate::xml_builder::*; use crate::xml_builder::*;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct CommentRangeStart<'a> { pub struct CommentRangeStart {
id: &'a str, id: String,
comment: Comment<'a>, comment: Comment,
} }
impl<'a> CommentRangeStart<'a> { impl CommentRangeStart {
pub fn new(comment: Comment<'a>) -> CommentRangeStart<'a> { pub fn new(comment: Comment) -> CommentRangeStart {
CommentRangeStart { CommentRangeStart {
id: comment.id(), id: comment.id(),
comment, comment,
} }
} }
pub(crate) fn comment(&self) -> Comment<'a> { pub(crate) fn comment(&self) -> Comment {
self.comment.clone() self.comment.clone()
} }
} }
impl<'a> BuildXML for CommentRangeStart<'a> { impl BuildXML for CommentRangeStart {
fn build(&self) -> Vec<u8> { fn build(&self) -> Vec<u8> {
let b = XMLBuilder::new(); let b = XMLBuilder::new();
b.comment_range_start(&self.id).build() b.comment_range_start(&self.id).build()

View File

@ -2,39 +2,39 @@ use crate::documents::{BuildXML, HistoryId, Run};
use crate::xml_builder::*; use crate::xml_builder::*;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Delete<'a> { pub struct Delete {
author: &'a str, author: String,
date: &'a str, date: String,
run: Run<'a>, run: Run,
} }
impl<'a> Default for Delete<'a> { impl Default for Delete {
fn default() -> Delete<'a> { fn default() -> Delete {
Delete { Delete {
author: "unnamed", author: "unnamed".to_owned(),
date: "1970-01-01T00:00:00Z", date: "1970-01-01T00:00:00Z".to_owned(),
run: Run::new(), run: Run::new(),
} }
} }
} }
impl<'a> Delete<'a> { impl Delete {
pub fn new() -> Delete<'a> { pub fn new() -> Delete {
Default::default() Default::default()
} }
pub fn run(mut self, run: Run<'a>) -> Delete<'a> { pub fn run(mut self, run: Run) -> Delete {
self.run = run; self.run = run;
self 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<u8> { fn build(&self) -> Vec<u8> {
XMLBuilder::new() XMLBuilder::new()
.open_delete(&self.generate(), self.author, self.date) .open_delete(&self.generate(), &self.author, &self.date)
.add_child(&self.run) .add_child(&self.run)
.close() .close()
.build() .build()

View File

@ -2,39 +2,39 @@ use crate::documents::{BuildXML, HistoryId, Run};
use crate::xml_builder::*; use crate::xml_builder::*;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Insert<'a> { pub struct Insert {
author: &'a str, author: String,
date: &'a str, date: String,
run: Run<'a>, run: Run,
} }
impl<'a> Default for Insert<'a> { impl Default for Insert {
fn default() -> Insert<'a> { fn default() -> Insert {
Insert { Insert {
author: "unnamed", author: "unnamed".to_owned(),
date: "1970-01-01T00:00:00Z", date: "1970-01-01T00:00:00Z".to_owned(),
run: Run::new(), run: Run::new(),
} }
} }
} }
impl<'a> Insert<'a> { impl Insert {
pub fn new() -> Insert<'a> { pub fn new() -> Insert {
Default::default() Default::default()
} }
pub fn run(mut self, run: Run<'a>) -> Insert<'a> { pub fn run(mut self, run: Run) -> Insert {
self.run = run; self.run = run;
self 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<u8> { fn build(&self) -> Vec<u8> {
XMLBuilder::new() XMLBuilder::new()
.open_insert(&self.generate(), self.author, self.date) .open_insert(&self.generate(), &self.author, &self.date)
.add_child(&self.run) .add_child(&self.run)
.close() .close()
.build() .build()

View File

@ -3,23 +3,23 @@ use crate::types::*;
use crate::xml_builder::*; use crate::xml_builder::*;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Level<'a> { pub struct Level {
level: usize, level: usize,
start: Start, start: Start,
format: NumberFormat<'a>, format: NumberFormat,
text: LevelText<'a>, text: LevelText,
jc: LevelJc<'a>, jc: LevelJc,
paragraph_property: ParagraphProperty, paragraph_property: ParagraphProperty,
} }
impl<'a> Level<'a> { impl Level {
pub fn new( pub fn new(
level: usize, level: usize,
start: Start, start: Start,
format: NumberFormat<'a>, format: NumberFormat,
text: LevelText<'a>, text: LevelText,
jc: LevelJc<'a>, jc: LevelJc,
) -> Level<'a> { ) -> Level {
Self { Self {
level, level,
start, start,
@ -36,7 +36,7 @@ impl<'a> Level<'a> {
} }
} }
impl<'a> BuildXML for Level<'a> { impl BuildXML for Level {
fn build(&self) -> Vec<u8> { fn build(&self) -> Vec<u8> {
XMLBuilder::new() XMLBuilder::new()
.open_level(&format!("{}", self.level)) .open_level(&format!("{}", self.level))

View File

@ -2,20 +2,20 @@ use crate::documents::BuildXML;
use crate::xml_builder::*; use crate::xml_builder::*;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct LevelJc<'a> { pub struct LevelJc {
val: &'a str, val: String,
} }
impl<'a> LevelJc<'a> { impl LevelJc {
pub fn new(val: &'a str) -> Self { pub fn new(val: impl Into<String>) -> Self {
Self { val } Self { val: val.into() }
} }
} }
impl<'a> BuildXML for LevelJc<'a> { impl BuildXML for LevelJc {
fn build(&self) -> Vec<u8> { fn build(&self) -> Vec<u8> {
let b = XMLBuilder::new(); let b = XMLBuilder::new();
b.level_justification(self.val).build() b.level_justification(&self.val).build()
} }
} }

View File

@ -2,20 +2,20 @@ use crate::documents::BuildXML;
use crate::xml_builder::*; use crate::xml_builder::*;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct LevelText<'a> { pub struct LevelText {
val: &'a str, val: String,
} }
impl<'a> LevelText<'a> { impl LevelText {
pub fn new(val: &'a str) -> Self { pub fn new(val: impl Into<String>) -> Self {
Self { val } Self { val: val.into() }
} }
} }
impl<'a> BuildXML for LevelText<'a> { impl BuildXML for LevelText {
fn build(&self) -> Vec<u8> { fn build(&self) -> Vec<u8> {
let b = XMLBuilder::new(); let b = XMLBuilder::new();
b.level_text(self.val).build() b.level_text(&self.val).build()
} }
} }

View File

@ -2,20 +2,20 @@ use crate::documents::BuildXML;
use crate::xml_builder::*; use crate::xml_builder::*;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct NumberFormat<'a> { pub struct NumberFormat {
val: &'a str, val: String,
} }
impl<'a> NumberFormat<'a> { impl NumberFormat {
pub fn new(val: &'a str) -> Self { pub fn new(val: impl Into<String>) -> Self {
Self { val } Self { val: val.into() }
} }
} }
impl<'a> BuildXML for NumberFormat<'a> { impl BuildXML for NumberFormat {
fn build(&self) -> Vec<u8> { fn build(&self) -> Vec<u8> {
let b = XMLBuilder::new(); let b = XMLBuilder::new();
b.number_format(self.val).build() b.number_format(&self.val).build()
} }
} }

View File

@ -2,23 +2,23 @@ use crate::documents::{BuildXML, Level};
use crate::xml_builder::*; use crate::xml_builder::*;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Numbering<'a> { pub struct Numbering {
id: usize, id: usize,
levels: Vec<Level<'a>>, levels: Vec<Level>,
} }
impl<'a> Numbering<'a> { impl Numbering {
pub fn new(id: usize) -> Self { pub fn new(id: usize) -> Self {
Self { id, levels: vec![] } 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.levels.push(level);
self self
} }
} }
impl<'a> BuildXML for Numbering<'a> { impl BuildXML for Numbering {
fn build(&self) -> Vec<u8> { fn build(&self) -> Vec<u8> {
let id = format!("{}", self.id); let id = format!("{}", self.id);
let mut b = XMLBuilder::new(); let mut b = XMLBuilder::new();

View File

@ -4,13 +4,13 @@ use crate::types::*;
use crate::xml_builder::*; use crate::xml_builder::*;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Paragraph<'a> { pub struct Paragraph {
pub(crate) children: Vec<ParagraphChild<'a>>, pub(crate) children: Vec<ParagraphChild>,
property: ParagraphProperty, property: ParagraphProperty,
attrs: Vec<(String, String)>, attrs: Vec<(String, String)>,
} }
impl<'a> Default for Paragraph<'a> { impl Default for Paragraph {
fn default() -> Self { fn default() -> Self {
Self { Self {
children: Vec::new(), children: Vec::new(),
@ -21,17 +21,17 @@ impl<'a> Default for Paragraph<'a> {
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum ParagraphChild<'a> { pub enum ParagraphChild {
Run(Run<'a>), Run(Run),
Insert(Insert<'a>), Insert(Insert),
Delete(Delete<'a>), Delete(Delete),
BookmarkStart(BookmarkStart<'a>), BookmarkStart(BookmarkStart),
BookmarkEnd(BookmarkEnd<'a>), BookmarkEnd(BookmarkEnd),
CommentStart(CommentRangeStart<'a>), CommentStart(CommentRangeStart),
CommentEnd(CommentRangeEnd<'a>), CommentEnd(CommentRangeEnd),
} }
impl<'a> BuildXML for ParagraphChild<'a> { impl BuildXML for ParagraphChild {
fn build(&self) -> Vec<u8> { fn build(&self) -> Vec<u8> {
match self { match self {
ParagraphChild::Run(v) => v.build(), ParagraphChild::Run(v) => v.build(),
@ -45,8 +45,8 @@ impl<'a> BuildXML for ParagraphChild<'a> {
} }
} }
impl<'a> Paragraph<'a> { impl Paragraph {
pub fn new() -> Paragraph<'a> { pub fn new() -> Paragraph {
Default::default() Default::default()
} }
@ -54,39 +54,43 @@ impl<'a> Paragraph<'a> {
&self.children &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.children.push(ParagraphChild::Run(run));
self 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.children.push(ParagraphChild::Insert(insert));
self 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.children.push(ParagraphChild::Delete(delete));
self self
} }
pub fn add_attr(mut self, key: impl Into<String>, val: impl Into<String>) -> Paragraph<'a> { pub fn add_attr(mut self, key: impl Into<String>, val: impl Into<String>) -> Paragraph {
self.attrs.push((key.into(), val.into())); self.attrs.push((key.into(), val.into()));
self 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<String>,
name: impl Into<String>,
) -> Paragraph {
self.children self.children
.push(ParagraphChild::BookmarkStart(BookmarkStart::new(id, name))); .push(ParagraphChild::BookmarkStart(BookmarkStart::new(id, name)));
self self
} }
pub fn add_bookmark_end(mut self, id: &'a str) -> Paragraph<'a> { pub fn add_bookmark_end(mut self, id: impl Into<String>) -> Paragraph {
self.children self.children
.push(ParagraphChild::BookmarkEnd(BookmarkEnd::new(id))); .push(ParagraphChild::BookmarkEnd(BookmarkEnd::new(id)));
self 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 self.children
.push(ParagraphChild::CommentStart(CommentRangeStart::new( .push(ParagraphChild::CommentStart(CommentRangeStart::new(
comment, comment,
@ -94,27 +98,23 @@ impl<'a> Paragraph<'a> {
self self
} }
pub fn add_comment_end(mut self, id: &'a str) -> Paragraph<'a> { pub fn add_comment_end(mut self, id: impl Into<String>) -> Paragraph {
self.children self.children
.push(ParagraphChild::CommentEnd(CommentRangeEnd::new(id))); .push(ParagraphChild::CommentEnd(CommentRangeEnd::new(id)));
self 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.property = self.property.align(alignment_type);
self 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.property = self.property.style(style_id);
self self
} }
pub fn indent( pub fn indent(mut self, left: usize, special_indent: Option<SpecialIndentType>) -> Paragraph {
mut self,
left: usize,
special_indent: Option<SpecialIndentType>,
) -> Paragraph<'a> {
self.property = self.property.indent(left, special_indent); self.property = self.property.indent(left, special_indent);
self self
} }
@ -125,7 +125,7 @@ impl<'a> Paragraph<'a> {
} }
} }
impl<'a> BuildXML for Paragraph<'a> { impl BuildXML for Paragraph {
fn build(&self) -> Vec<u8> { fn build(&self) -> Vec<u8> {
XMLBuilder::new() XMLBuilder::new()
.open_paragraph(&self.attrs) .open_paragraph(&self.attrs)

View File

@ -1,6 +1,4 @@
use super::{ use super::*;
Indent, IndentLevel, Justification, NumberingId, NumberingProperty, ParagraphStyle, RunProperty,
};
use crate::documents::BuildXML; use crate::documents::BuildXML;
use crate::types::{AlignmentType, SpecialIndentType}; use crate::types::{AlignmentType, SpecialIndentType};
use crate::xml_builder::*; use crate::xml_builder::*;

View File

@ -4,12 +4,12 @@ use crate::types::BreakType;
use crate::xml_builder::*; use crate::xml_builder::*;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Run<'a> { pub struct Run {
run_property: RunProperty, run_property: RunProperty,
children: Vec<RunChild<'a>>, children: Vec<RunChild>,
} }
impl<'a> Default for Run<'a> { impl Default for Run {
fn default() -> Self { fn default() -> Self {
let run_property = RunProperty::new(); let run_property = RunProperty::new();
Self { Self {
@ -20,72 +20,72 @@ impl<'a> Default for Run<'a> {
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum RunChild<'a> { pub enum RunChild {
Text(Text<'a>), Text(Text),
DeleteText(DeleteText), DeleteText(DeleteText),
Tab(Tab), Tab(Tab),
Break(Break), Break(Break),
} }
impl<'a> Run<'a> { impl Run {
pub fn new() -> Run<'a> { pub fn new() -> Run {
Run { Run {
..Default::default() ..Default::default()
} }
} }
pub fn add_text(mut self, text: &'a str) -> Run<'a> { pub fn add_text(mut self, text: impl Into<String>) -> Run {
self.children.push(RunChild::Text(Text::new(text))); self.children.push(RunChild::Text(Text::new(text)));
self self
} }
pub fn add_delete_text(mut self, text: &'a str) -> Run<'a> { pub fn add_delete_text(mut self, text: impl Into<String>) -> Run {
self.children.push(RunChild::Text(Text::new(text))); self.children.push(RunChild::Text(Text::new(text)));
self self
} }
pub fn add_tab(mut self) -> Run<'a> { pub fn add_tab(mut self) -> Run {
self.children.push(RunChild::Tab(Tab::new())); self.children.push(RunChild::Tab(Tab::new()));
self 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.children.push(RunChild::Break(Break::new(break_type)));
self 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.run_property = self.run_property.size(size);
self self
} }
pub fn color(mut self, color: &'a str) -> Run<'a> { pub fn color(mut self, color: impl Into<String>) -> Run {
self.run_property = self.run_property.color(color); self.run_property = self.run_property.color(color);
self self
} }
pub fn highlight(mut self, color: &'a str) -> Run<'a> { pub fn highlight(mut self, color: impl Into<String>) -> Run {
self.run_property = self.run_property.highlight(color); self.run_property = self.run_property.highlight(color);
self self
} }
pub fn bold(mut self) -> Run<'a> { pub fn bold(mut self) -> Run {
self.run_property = self.run_property.bold(); self.run_property = self.run_property.bold();
self self
} }
pub fn italic(mut self) -> Run<'a> { pub fn italic(mut self) -> Run {
self.run_property = self.run_property.italic(); self.run_property = self.run_property.italic();
self self
} }
pub fn underline(mut self, line_type: &'a str) -> Run<'a> { pub fn underline(mut self, line_type: impl Into<String>) -> Run {
self.run_property = self.run_property.underline(line_type); self.run_property = self.run_property.underline(line_type);
self self
} }
} }
impl<'a> BuildXML for Run<'a> { impl BuildXML for Run {
fn build(&self) -> Vec<u8> { fn build(&self) -> Vec<u8> {
let b = XMLBuilder::new(); let b = XMLBuilder::new();
let mut b = b.open_run().add_child(&self.run_property); let mut b = b.open_run().add_child(&self.run_property);

View File

@ -26,12 +26,12 @@ impl RunProperty {
self self
} }
pub fn color(mut self, color: &str) -> RunProperty { pub fn color(mut self, color: impl Into<String>) -> RunProperty {
self.color = Some(Color::new(color)); self.color = Some(Color::new(color));
self self
} }
pub fn highlight(mut self, color: &str) -> RunProperty { pub fn highlight(mut self, color: impl Into<String>) -> RunProperty {
self.highlight = Some(Highlight::new(color)); self.highlight = Some(Highlight::new(color));
self self
} }
@ -48,7 +48,7 @@ impl RunProperty {
self self
} }
pub fn underline(mut self, line_type: &str) -> RunProperty { pub fn underline(mut self, line_type: impl Into<String>) -> RunProperty {
self.underline = Some(Underline::new(line_type)); self.underline = Some(Underline::new(line_type));
self self
} }

View File

@ -3,14 +3,14 @@ use crate::documents::BuildXML;
use crate::xml_builder::*; use crate::xml_builder::*;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Table<'a> { pub struct Table {
pub(crate) rows: Vec<TableRow<'a>>, pub(crate) rows: Vec<TableRow>,
property: TableProperty, property: TableProperty,
grid: Vec<usize>, grid: Vec<usize>,
} }
impl<'a> Table<'a> { impl Table {
pub fn new(rows: Vec<TableRow<'a>>) -> Table<'a> { pub fn new(rows: Vec<TableRow>) -> Table {
let property = TableProperty::new(); let property = TableProperty::new();
let grid = vec![]; let grid = vec![];
Self { Self {
@ -20,13 +20,13 @@ impl<'a> Table<'a> {
} }
} }
pub fn set_grid(mut self, grid: Vec<usize>) -> Table<'a> { pub fn set_grid(mut self, grid: Vec<usize>) -> Table {
self.grid = grid; self.grid = grid;
self self
} }
} }
impl<'a> BuildXML for Table<'a> { impl BuildXML for Table {
fn build(&self) -> Vec<u8> { fn build(&self) -> Vec<u8> {
let grid = TableGrid::new(self.grid.clone()); let grid = TableGrid::new(self.grid.clone());
let b = XMLBuilder::new() let b = XMLBuilder::new()

View File

@ -4,40 +4,40 @@ use crate::types::*;
use crate::xml_builder::*; use crate::xml_builder::*;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct TableCell<'a> { pub struct TableCell {
pub(crate) contents: Vec<TableCellContent<'a>>, pub(crate) contents: Vec<TableCellContent>,
property: TableCellProperty, property: TableCellProperty,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum TableCellContent<'a> { pub enum TableCellContent {
Paragraph(Paragraph<'a>), Paragraph(Paragraph),
} }
impl<'a> TableCell<'a> { impl TableCell {
pub fn new() -> TableCell<'a> { pub fn new() -> TableCell {
let property = TableCellProperty::new(); let property = TableCellProperty::new();
let contents = vec![]; let contents = vec![];
Self { property, contents } 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.contents.push(TableCellContent::Paragraph(p));
self 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.property = self.property.vertical_merge(t);
self 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.property = self.property.grid_span(v);
self self
} }
} }
impl<'a> BuildXML for TableCell<'a> { impl BuildXML for TableCell {
fn build(&self) -> Vec<u8> { fn build(&self) -> Vec<u8> {
let b = XMLBuilder::new(); let b = XMLBuilder::new();
let mut b = b.open_table_cell().add_child(&self.property); let mut b = b.open_table_cell().add_child(&self.property);

View File

@ -3,19 +3,19 @@ use crate::documents::BuildXML;
use crate::xml_builder::*; use crate::xml_builder::*;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct TableRow<'a> { pub struct TableRow {
pub(crate) cells: Vec<TableCell<'a>>, pub(crate) cells: Vec<TableCell>,
property: TableRowProperty, property: TableRowProperty,
} }
impl<'a> TableRow<'a> { impl TableRow {
pub fn new(cells: Vec<TableCell<'a>>) -> TableRow<'a> { pub fn new(cells: Vec<TableCell>) -> TableRow {
let property = TableRowProperty::new(); let property = TableRowProperty::new();
Self { property, cells } Self { property, cells }
} }
} }
impl<'a> BuildXML for TableRow<'a> { impl BuildXML for TableRow {
fn build(&self) -> Vec<u8> { fn build(&self) -> Vec<u8> {
let b = XMLBuilder::new() let b = XMLBuilder::new()
.open_table_row() .open_table_row()

View File

@ -2,13 +2,13 @@ use crate::documents::BuildXML;
use crate::xml_builder::*; use crate::xml_builder::*;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Text<'a> { pub struct Text {
text: &'a str, text: String,
preserve_space: bool, preserve_space: bool,
} }
impl<'a> Text<'a> { impl Text {
pub fn new(text: &'a str) -> Text { pub fn new(text: impl Into<String>) -> Text {
Text { Text {
text: text.into(), text: text.into(),
preserve_space: true, 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<u8> { fn build(&self) -> Vec<u8> {
XMLBuilder::new().text(&self.text, true).build() XMLBuilder::new().text(&self.text, true).build()
} }

View File

@ -30,20 +30,20 @@ pub use styles::*;
pub use xml_docx::*; pub use xml_docx::*;
#[derive(Debug)] #[derive(Debug)]
pub struct Docx<'a> { pub struct Docx {
content_type: ContentTypes, content_type: ContentTypes,
rels: Rels, rels: Rels,
document_rels: DocumentRels, document_rels: DocumentRels,
doc_props: DocProps<'a>, doc_props: DocProps,
styles: Styles, styles: Styles,
document: Document<'a>, document: Document,
comments: Comments<'a>, comments: Comments,
numberings: Numberings<'a>, numberings: Numberings,
settings: Settings, settings: Settings,
font_table: FontTable, font_table: FontTable,
} }
impl<'a> Default for Docx<'a> { impl Default for Docx {
fn default() -> Self { fn default() -> Self {
let content_type = ContentTypes::new(); let content_type = ContentTypes::new();
let rels = Rels::new(); let rels = Rels::new();
@ -70,22 +70,22 @@ impl<'a> Default for Docx<'a> {
} }
} }
impl<'a> Docx<'a> { impl Docx {
pub fn new() -> Docx<'a> { pub fn new() -> Docx {
Default::default() 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.document = self.document.add_paragraph(p);
self 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.document = self.document.add_table(t);
self self
} }
pub fn add_numbering(mut self, num: Numbering<'a>) -> Docx<'a> { pub fn add_numbering(mut self, num: Numbering) -> Docx {
self.numberings = self.numberings.add_numbering(num); self.numberings = self.numberings.add_numbering(num);
self self
} }
@ -108,7 +108,7 @@ impl<'a> Docx<'a> {
// Traverse and clone comments from document and add to comments node. // Traverse and clone comments from document and add to comments node.
fn update_comments(&mut self) { fn update_comments(&mut self) {
let mut comments: Vec<Comment<'a>> = vec![]; let mut comments: Vec<Comment> = vec![];
for child in &self.document.children { for child in &self.document.children {
match child { match child {
DocumentChild::Paragraph(paragraph) => { DocumentChild::Paragraph(paragraph) => {

View File

@ -4,28 +4,28 @@ use crate::types::*;
use crate::xml_builder::*; use crate::xml_builder::*;
#[derive(Debug)] #[derive(Debug)]
pub struct Numberings<'a> { pub struct Numberings {
numberings: Vec<Numbering<'a>>, numberings: Vec<Numbering>,
} }
impl<'a> Numberings<'a> { impl Numberings {
pub fn new() -> Self { pub fn new() -> Self {
Default::default() Default::default()
} }
pub fn add_numbering(mut self, n: Numbering<'a>) -> Self { pub fn add_numbering(mut self, n: Numbering) -> Self {
self.numberings.push(n); self.numberings.push(n);
self self
} }
} }
impl<'a> Default for Numberings<'a> { impl Default for Numberings {
fn default() -> Self { fn default() -> Self {
Self { numberings: vec![] } Self { numberings: vec![] }
} }
} }
impl<'a> BuildXML for Numberings<'a> { impl BuildXML for Numberings {
fn build(&self) -> Vec<u8> { fn build(&self) -> Vec<u8> {
let mut b = XMLBuilder::new().declaration(Some(true)).open_numbering(); let mut b = XMLBuilder::new().declaration(Some(true)).open_numbering();
b = b.add_child(&create_default_numbering()); b = b.add_child(&create_default_numbering());
@ -36,7 +36,7 @@ impl<'a> BuildXML for Numberings<'a> {
} }
} }
fn create_default_numbering() -> Numbering<'static> { fn create_default_numbering() -> Numbering {
Numbering::new(0) Numbering::new(0)
.add_level( .add_level(
Level::new( Level::new(

View File

@ -1 +1,22 @@
<w:styles xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" mc:Ignorable="w14 w15"><w:docDefaults><w:rPrDefault><w:rPr /></w:rPrDefault></w:docDefaults><w:style w:type="paragraph" w:styleId="Normal"><w:name w:val="Normal" /><w:rPr /><w:pPr><w:pStyle w:val="Normal" /><w:rPr /></w:pPr><w:basedOn w:val="Normal" /><w:next w:val="Normal" /><w:qFormat /></w:style></w:styles> <w:styles xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml"
xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" mc:Ignorable="w14 w15">
<w:docDefaults>
<w:rPrDefault>
<w:rPr />
</w:rPrDefault>
</w:docDefaults>
<w:style w:type="paragraph" w:styleId="Normal">
<w:name w:val="Normal" />
<w:rPr />
<w:pPr>
<w:pStyle w:val="Normal" />
<w:rPr />
</w:pPr>
<w:basedOn w:val="Normal" />
<w:next w:val="Normal" />
<w:qFormat />
</w:style>
</w:styles>

View File

@ -6,7 +6,11 @@ const rust = import("./pkg");
rust rust
.then(m => { .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"); saveAs(new Blob([docx.build()]), "example.docx");
docx.free();
}) })
.catch(console.error); .catch(console.error);

View File

@ -3,20 +3,17 @@ use wasm_bindgen::prelude::*;
#[wasm_bindgen] #[wasm_bindgen]
#[derive(Debug)] #[derive(Debug)]
pub struct Docx(docx_core::Docx<'static>); pub struct Docx(docx_core::Docx);
#[wasm_bindgen] #[wasm_bindgen(js_name = createDocx)]
#[allow(non_snake_case)] pub fn create_docx() -> Docx {
pub fn createDocx() -> Docx {
Docx(docx_core::Docx::new()) Docx(docx_core::Docx::new())
} }
#[wasm_bindgen] #[wasm_bindgen]
impl Docx { impl Docx {
pub fn add_paragraph(mut self) -> Self { pub fn add_paragraph(mut self, p: Paragraph) -> Self {
self.0 = self.0.add_paragraph( self.0 = self.0.add_paragraph(p.0);
docx_core::Paragraph::new().add_run(docx_core::Run::new().add_text("Hello")),
);
self self
} }
@ -29,8 +26,38 @@ impl Docx {
} }
Ok(cur.into_inner()) Ok(cur.into_inner())
} }
}
pub fn test(&self, t: docx_core::StyleType) { #[wasm_bindgen]
() #[derive(Debug)]
pub struct Paragraph(docx_core::Paragraph);
#[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
} }
} }