feat: Add rels

main
bokuweb 2019-11-05 18:03:23 +09:00
parent 7925fc4e24
commit 3e154d6904
10 changed files with 219 additions and 19 deletions

View File

@ -1,3 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/><Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/>
<Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/>
<Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/>
</Relationships>

View File

@ -1,4 +1,4 @@
use super::xml_builder::*;
use crate::xml_builder::*;
pub struct ContentTypes {}
@ -9,7 +9,7 @@ impl ContentTypes {
pub fn build(&self) -> Vec<u8> {
let b = XMLBuilder::new();
b.add_declaration()
b.declaration()
.open_types("http://schemas.openxmlformats.org/package/2006/content-types")
.add_override(
"/_rels/.rels",
@ -60,7 +60,7 @@ mod tests {
let b = c.build();
assert_eq!(
str::from_utf8(&b).unwrap(),
r#"<?xml version="1.0" encoding="UTF-8" />
r#"<?xml version="1.0" encoding="UTF-8"?>
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
<Override PartName="/_rels/.rels" ContentType="application/vnd.openxmlformats-package.relationships+xml" />
<Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml" />

View File

@ -1,16 +1,19 @@
pub mod content_types;
mod xml_builder;
mod content_types;
mod rels;
mod xml_document;
use content_types::*;
use rels::*;
pub(crate) struct Document {
content_type: ContentTypes,
rels: Rels,
}
impl Document {
pub fn new() -> Document {
let content_type = ContentTypes::new();
Document { content_type }
let rels = Rels::new();
Document { content_type, rels }
}
}

View File

@ -0,0 +1,54 @@
use crate::xml_builder::*;
pub struct Rels {}
impl Rels {
pub fn new() -> Rels {
Rels {}
}
pub fn build(&self) -> Vec<u8> {
let b = XMLBuilder::new();
b.declaration()
.open_relationships("http://schemas.openxmlformats.org/package/2006/relationships")
.relationship(
"rId1",
"http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties",
"docProps/core.xml"
)
.relationship(
"rId2",
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties",
"docProps/app.xml"
)
.relationship(
"rId3",
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument",
"word/document.xml"
)
.close()
.build()
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::str;
#[test]
fn test_build() {
let c = Rels::new();
let b = c.build();
assert_eq!(
str::from_utf8(&b).unwrap(),
r#"<?xml version="1.0" encoding="UTF-8"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml" />
<Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml" />
<Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml" />
</Relationships>"#
);
}
}

View File

@ -2,11 +2,15 @@ use super::Document;
pub(crate) struct XMLDocument {
content_type: Vec<u8>,
rels: Vec<u8>,
}
impl From<Document> for XMLDocument {
fn from(doc: Document) -> XMLDocument {
let content_type = doc.content_type.build();
XMLDocument { content_type }
XMLDocument {
content_type,
rels: vec![],
}
}
}

View File

@ -1,6 +1,8 @@
mod documents;
mod xml_builder;
use documents::*;
use xml_builder::*;
use std::fs::File;
use std::io::{self, Write};

View File

@ -0,0 +1,33 @@
use super::XMLBuilder;
impl XMLBuilder {
// Build XML declaration
// i.e. <?xml version="1.0" encoding="UTF-8"?>
pub(crate) fn declaration(mut self) -> Self {
self.writer
.write(super::XmlEvent::StartDocument {
version: super::XmlVersion::Version10,
encoding: Some("UTF-8"),
standalone: None,
})
.expect("should write to buf");
self
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::str;
#[test]
fn test_declaration() {
let b = XMLBuilder::new();
let r = b.declaration().build();
assert_eq!(
str::from_utf8(&r).unwrap(),
r#"<?xml version="1.0" encoding="UTF-8"?>"#
);
}
}

View File

@ -0,0 +1,37 @@
macro_rules! opened_el {
($name: ident, $el_name: expr, $attr0: expr) => {
pub(crate) fn $name(mut self, arg0: &str) -> Self {
self.writer
.write(super::XmlEvent::start_element($el_name).attr($attr0, arg0))
.expect("should write to buf");
self
}
};
}
macro_rules! closed_el {
($name: ident, $el_name: expr, $attr0: expr) => {
pub(crate) fn $name(mut self, arg0: &str) -> Self {
self.writer
.write(super::XmlEvent::start_element($el_name).attr($attr0, arg0))
.expect("should write to buf");
self.close()
}
};
($name: ident, $el_name: expr, $attr0: expr, $attr1: expr) => {
pub(crate) fn $name(mut self, arg0: &str, arg1: &str) -> Self {
self.writer
.write(super::XmlEvent::start_element($el_name).attr($attr0, arg0).attr($attr1, arg1))
.expect("should write to buf");
self.close()
}
};
($name: ident, $el_name: expr, $attr0: expr, $attr1: expr, $attr2: expr) => {
pub(crate) fn $name(mut self, arg0: &str, arg1: &str, arg2: &str) -> Self {
self.writer
.write(super::XmlEvent::start_element($el_name).attr($attr0, arg0).attr($attr1, arg1).attr($attr2, arg2))
.expect("should write to buf");
self.close()
}
};
}

View File

@ -1,3 +1,9 @@
#[macro_use]
mod macros;
mod declaration;
mod relationship;
use xml::common::XmlVersion;
use xml::writer::{EmitterConfig, EventWriter, XmlEvent};
pub struct XMLBuilder {
@ -14,17 +20,8 @@ impl XMLBuilder {
XMLBuilder { writer }
}
pub(crate) fn add_declaration(mut self) -> Self {
self.writer
.write(
XmlEvent::start_element("?xml")
.attr("version", "1.0")
.attr("encoding", "UTF-8"),
)
.expect("should write to buf");
self.close()
}
// Build types element
// i.e. <Types xmlns="http://...">
pub(crate) fn open_types(mut self, uri: &str) -> Self {
self.writer
.write(XmlEvent::start_element("Types").attr("xmlns", uri))
@ -32,6 +29,8 @@ impl XMLBuilder {
self
}
// Build Override element
// i.e. <Override PartName="/_rels/.rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>
pub(crate) fn add_override(mut self, name: &str, content_type: &str) -> Self {
self.writer
.write(
@ -43,6 +42,7 @@ impl XMLBuilder {
self.close()
}
// Close tag
pub(crate) fn close(mut self) -> Self {
self.writer
.write(XmlEvent::end_element())
@ -50,7 +50,30 @@ impl XMLBuilder {
self
}
// Write plain text
pub(crate) fn text(mut self, t: &str) -> Self {
self.writer.write(t).unwrap();
self
}
pub(crate) fn build(self) -> Vec<u8> {
self.writer.into_inner()
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::str;
#[test]
fn test_open_types() {
let b = XMLBuilder::new();
let r = b.open_types("http://example").text("child").close().build();
assert_eq!(
str::from_utf8(&r).unwrap(),
r#"<Types xmlns="http://example">child</Types>"#
);
}
}

View File

@ -0,0 +1,41 @@
use super::XMLBuilder;
impl XMLBuilder {
// Build RelationShips element
// i.e. <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
opened_el!(open_relationships, "Relationships", "xmlns");
// Build Relationship
closed_el!(relationship, "Relationship", "Id", "Type", "Target");
}
#[cfg(test)]
mod tests {
use super::XMLBuilder;
use std::str;
#[test]
fn test_open_relationships() {
let b = XMLBuilder::new();
let r = b
.open_relationships("http://example")
.text("child")
.close()
.build();
assert_eq!(
str::from_utf8(&r).unwrap(),
r#"<Relationships xmlns="http://example">child</Relationships>"#
);
}
#[test]
fn test_relationship() {
let b = XMLBuilder::new();
let r = b.relationship("rId1", "http://example", "core.xml").build();
assert_eq!(
str::from_utf8(&r).unwrap(),
r#"<Relationship Id="rId1" Type="http://example" Target="core.xml" />"#
);
}
}