aboutsummaryrefslogtreecommitdiffstats
path: root/src/writer.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/writer.rs')
-rw-r--r--src/writer.rs75
1 files changed, 61 insertions, 14 deletions
diff --git a/src/writer.rs b/src/writer.rs
index dc5b48a..e319fdc 100644
--- a/src/writer.rs
+++ b/src/writer.rs
@@ -5,10 +5,11 @@ use futures::Sink;
use tokio::io::{AsyncWrite, AsyncWriteExt};
use crate::{
- element::{escape_str, Content, Element, Name, NamespaceDeclaration},
+ declaration::{Declaration, VersionInfo},
+ element::{escape_str, Content, Element, IntoElement, Name, NamespaceDeclaration},
error::Error,
- xml::{self, composers::Composer, parsers_complete::Parser, ETag},
- Result,
+ xml::{self, composers::Composer, parsers_complete::Parser, ETag, XMLDecl},
+ Result, XMLNS_NS, XML_NS,
};
// pub struct Writer<W, C = Composer> {
@@ -20,21 +21,69 @@ pub struct Writer<W> {
impl<W> Writer<W> {
pub fn new(writer: W) -> Self {
+ let mut default_declarations = HashSet::new();
+ default_declarations.insert(NamespaceDeclaration {
+ prefix: Some("xml".to_string()),
+ namespace: XML_NS.to_string(),
+ });
+ default_declarations.insert(NamespaceDeclaration {
+ prefix: Some("xmlns".to_string()),
+ namespace: XMLNS_NS.to_string(),
+ });
Self {
inner: writer,
depth: Vec::new(),
- namespace_declarations: Vec::new(),
+ namespace_declarations: vec![default_declarations],
}
}
+
+ pub fn into_inner(self) -> W {
+ self.inner
+ }
}
impl<W: AsyncWrite + Unpin + Send> Writer<W> {
+ pub async fn write_declaration(&mut self, version: VersionInfo) -> Result<()> {
+ let declaration = Declaration::version(version);
+ let version_info;
+ match declaration.version_info {
+ VersionInfo::One => version_info = xml::VersionInfo::SingleQuoted(xml::VersionNum::One),
+ VersionInfo::OneDotOne => {
+ version_info = xml::VersionInfo::SingleQuoted(xml::VersionNum::OneDotOne)
+ }
+ }
+ let declaration = xml::XMLDecl {
+ version_info,
+ encoding_decl: None,
+ sd_decl: None,
+ };
+ declaration.write(&mut self.inner).await?;
+ Ok(())
+ }
+
+ pub async fn write_full(&mut self, into_element: &impl IntoElement) -> Result<()> {
+ let element = into_element.into_element();
+ Ok(self.write_element(&element).await?)
+ }
+
+ pub async fn write_start(&mut self, into_element: &impl IntoElement) -> Result<()> {
+ let element = into_element.into_element();
+ Ok(self.write_element_start(&element).await?)
+ }
+
+ pub async fn write_all_content(&mut self, into_element: &impl IntoElement) -> Result<()> {
+ for content in &into_element.get_content() {
+ self.write_content(content).await?;
+ }
+ Ok(())
+ }
+
#[async_recursion]
pub async fn write_element(&mut self, element: &Element) -> Result<()> {
if element.content.is_empty() {
self.write_empty(element).await?;
} else {
- self.write_start(element).await?;
+ self.write_element_start(element).await?;
for content in &element.content {
self.write_content(content).await?;
}
@@ -107,12 +156,11 @@ impl<W: AsyncWrite + Unpin + Send> Writer<W> {
if let Some(prefix) = &prefix {
att_name = xml::QName::PrefixedName(xml::PrefixedName {
prefix: xml::Prefix::parse_full(prefix)?,
- local_part: xml::LocalPart::parse_full(&element.name.local_name)?,
+ local_part: xml::LocalPart::parse_full(&name.local_name)?,
})
} else {
- att_name = xml::QName::UnprefixedName(xml::UnprefixedName::parse_full(
- &element.name.local_name,
- )?)
+ att_name =
+ xml::QName::UnprefixedName(xml::UnprefixedName::parse_full(&name.local_name)?)
}
let value = xml::AttValue::from(value.as_str());
@@ -131,7 +179,7 @@ impl<W: AsyncWrite + Unpin + Send> Writer<W> {
Ok(())
}
- pub async fn write_start(&mut self, element: &Element) -> Result<()> {
+ pub async fn write_element_start(&mut self, element: &Element) -> Result<()> {
let namespace_declarations_stack: Vec<_> = self
.namespace_declarations
.iter()
@@ -195,12 +243,11 @@ impl<W: AsyncWrite + Unpin + Send> Writer<W> {
if let Some(prefix) = &prefix {
att_name = xml::QName::PrefixedName(xml::PrefixedName {
prefix: xml::Prefix::parse_full(prefix)?,
- local_part: xml::LocalPart::parse_full(&element.name.local_name)?,
+ local_part: xml::LocalPart::parse_full(&name.local_name)?,
})
} else {
- att_name = xml::QName::UnprefixedName(xml::UnprefixedName::parse_full(
- &element.name.local_name,
- )?)
+ att_name =
+ xml::QName::UnprefixedName(xml::UnprefixedName::parse_full(&name.local_name)?)
}
let value = xml::AttValue::from(value.as_str());