diff options
Diffstat (limited to 'src/writer.rs')
-rw-r--r-- | src/writer.rs | 75 |
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()); |