Compare commits

..

No commits in common. "caf8b7506e1fb1ccd8e3f43c897a02db90397dde" and "4c235b972e2400bd2bb92b74b12558b485dc7142" have entirely different histories.

5 changed files with 294 additions and 330 deletions

View File

@ -10,7 +10,7 @@ use crate::{
// when are namespaces names chosen then if they are automatically calculated // when are namespaces names chosen then if they are automatically calculated
// namespaces are held by readers and writers. // namespaces are held by readers and writers.
#[derive(PartialEq, Eq, Hash, Clone, Debug)] #[derive(PartialEq, Eq, Hash, Clone, Debug)]
pub struct NamespaceDeclaration { pub struct Namespace {
pub prefix: Option<String>, pub prefix: Option<String>,
pub namespace: String, pub namespace: String,
} }
@ -18,8 +18,8 @@ pub struct NamespaceDeclaration {
// names are qualified, they contain a reference to the namespace (held within the reader/writer) // names are qualified, they contain a reference to the namespace (held within the reader/writer)
#[derive(PartialEq, Eq, Hash, Clone, Debug)] #[derive(PartialEq, Eq, Hash, Clone, Debug)]
pub struct Name { pub struct Name {
pub namespace: String, pub namespace: Namespace,
pub local_name: String, pub name: String,
} }
#[derive(Debug)] #[derive(Debug)]
@ -40,7 +40,7 @@ pub struct Element {
// namespace: String, // namespace: String,
// hashmap of explicit namespace declarations on the element itself only // hashmap of explicit namespace declarations on the element itself only
// possibly not needed as can be calculated at write time depending on context and qualified namespace, and for reading, element validity and namespaces are kept track of by the reader. // possibly not needed as can be calculated at write time depending on context and qualified namespace, and for reading, element validity and namespaces are kept track of by the reader.
pub namespace_declarations: HashSet<NamespaceDeclaration>, pub namespace_decl: HashSet<Namespace>,
// attributes can be in a different namespace than the element. how to make sure they are valid? // attributes can be in a different namespace than the element. how to make sure they are valid?
// maybe include the namespace instead of or with the prefix // maybe include the namespace instead of or with the prefix
// you can calculate the prefix from the namespaced name and the current writer context // you can calculate the prefix from the namespaced name and the current writer context

View File

@ -1,6 +1,6 @@
use std::{num::ParseIntError, str::Utf8Error}; use std::{num::ParseIntError, str::Utf8Error};
use crate::element::{Name, NamespaceDeclaration}; use crate::element::{Name, Namespace};
#[derive(Debug)] #[derive(Debug)]
pub enum Error { pub enum Error {
@ -10,12 +10,11 @@ pub enum Error {
EntityProcessError(String), EntityProcessError(String),
// TODO: better choice for failures than string // TODO: better choice for failures than string
InvalidCharRef(String), InvalidCharRef(String),
DuplicateNameSpaceDeclaration(NamespaceDeclaration), DuplicateNameSpace(Namespace),
DuplicateAttribute(String), DuplicateAttribute(String),
UnqualifiedNamespace(String), UnqualifiedNamespace(String),
MismatchedEndTag(Name, Name), MismatchedEndTag(String, String),
NotInElement(String), NotInElement(String),
ExtraData(String),
} }
impl From<std::io::Error> for Error { impl From<std::io::Error> for Error {

View File

@ -13,7 +13,7 @@ use tokio::io::{AsyncBufRead, AsyncBufReadExt, AsyncRead, AsyncReadExt};
static MAX_STANZA_SIZE: usize = 65536; static MAX_STANZA_SIZE: usize = 65536;
use crate::{ use crate::{
element::{Content, Element, Name, NamespaceDeclaration}, element::{Content, Element, Name, Namespace},
error::Error, error::Error,
xml::{self, parsers::Parser}, xml::{self, parsers::Parser},
Result, Result,
@ -26,7 +26,7 @@ pub struct Reader<R> {
// holds which tags we are in atm over depth // holds which tags we are in atm over depth
// to have names reference namespaces could // to have names reference namespaces could
depth: Vec<Name>, depth: Vec<Name>,
namespace_declarations: Vec<HashSet<NamespaceDeclaration>>, namespaces: Vec<HashSet<Namespace>>,
} }
impl<R> Reader<R> { impl<R> Reader<R> {
@ -35,7 +35,7 @@ impl<R> Reader<R> {
inner: reader, inner: reader,
buffer: Buffer::with_capacity(MAX_STANZA_SIZE), buffer: Buffer::with_capacity(MAX_STANZA_SIZE),
depth: Vec::new(), depth: Vec::new(),
namespace_declarations: Vec::new(), namespaces: Vec::new(),
} }
} }
} }
@ -75,11 +75,8 @@ where
match xml::STag::parse(input) { match xml::STag::parse(input) {
Ok((rest, e)) => { Ok((rest, e)) => {
let len = self.buffer.available_data() - rest.as_bytes().len(); let len = self.buffer.available_data() - rest.as_bytes().len();
let element = Reader::<R>::start_tag_from_xml( let element =
&mut self.depth, Reader::<R>::start_tag_from_xml(&mut self.depth, &mut self.namespaces, e)?;
&mut self.namespace_declarations,
e,
)?;
self.buffer.consume(len); self.buffer.consume(len);
return Ok(element); return Ok(element);
} }
@ -100,11 +97,7 @@ where
match xml::ETag::parse(input) { match xml::ETag::parse(input) {
Ok((rest, e)) => { Ok((rest, e)) => {
let len = self.buffer.available_data() - rest.as_bytes().len(); let len = self.buffer.available_data() - rest.as_bytes().len();
Reader::<R>::end_tag_from_xml( Reader::<R>::end_tag_from_xml(&mut self.depth, &mut self.namespaces, e)?;
&mut self.depth,
&mut self.namespace_declarations,
e,
)?;
self.buffer.consume(len); self.buffer.consume(len);
return Ok(()); return Ok(());
} }
@ -125,8 +118,7 @@ where
match xml::Element::parse(input) { match xml::Element::parse(input) {
Ok((rest, e)) => { Ok((rest, e)) => {
let len = self.buffer.available_data() - rest.as_bytes().len(); let len = self.buffer.available_data() - rest.as_bytes().len();
let element = let element = Reader::<R>::element_from_xml(&mut self.namespaces, e)?;
Reader::<R>::element_from_xml(&mut self.namespace_declarations, e)?;
self.buffer.consume(len); self.buffer.consume(len);
return Ok(element); return Ok(element);
} }
@ -164,10 +156,8 @@ where
} else { } else {
let len = let len =
self.buffer.available_data() - rest.as_bytes().len(); self.buffer.available_data() - rest.as_bytes().len();
let element = Self::element_from_xml( let element =
&mut self.namespace_declarations, Self::element_from_xml(&mut self.namespaces, element)?;
element,
)?;
self.buffer.consume(len); self.buffer.consume(len);
return Ok(Content::Element(element)); return Ok(Content::Element(element));
} }
@ -219,15 +209,12 @@ where
match xml::ContentItem::parse(input) { match xml::ContentItem::parse(input) {
Ok((rest, content_item)) => match content_item { Ok((rest, content_item)) => match content_item {
xml::ContentItem::Element(element) => { xml::ContentItem::Element(element) => {
// text can still be empty
if !text.is_empty() { if !text.is_empty() {
return Ok(Content::Text(text)); return Ok(Content::Text(text));
} else { } else {
let len = self.buffer.available_data() - rest.as_bytes().len(); let len = self.buffer.available_data() - rest.as_bytes().len();
let element = Self::element_from_xml( let element =
&mut self.namespace_declarations, Self::element_from_xml(&mut self.namespaces, element)?;
element,
)?;
self.buffer.consume(len); self.buffer.consume(len);
return Ok(Content::Element(element)); return Ok(Content::Element(element));
} }
@ -277,12 +264,10 @@ where
impl<R> Reader<R> { impl<R> Reader<R> {
fn start_tag_from_xml( fn start_tag_from_xml(
depth: &mut Vec<Name>, depth: &mut Vec<Name>,
namespace_declarations: &mut Vec<HashSet<NamespaceDeclaration>>, namespaces: &mut Vec<HashSet<Namespace>>,
s_tag: xml::STag, s_tag: xml::STag,
) -> Result<Element> { ) -> Result<Element> {
// namespace declarations on element let mut namespace_declarations = HashSet::new();
let mut element_namespace_declarations = HashSet::new();
for (prefix, namespace) in s_tag.attributes.iter().filter_map(|attribute| { for (prefix, namespace) in s_tag.attributes.iter().filter_map(|attribute| {
if let xml::Attribute::NamespaceDeclaration { ns_name, value } = attribute { if let xml::Attribute::NamespaceDeclaration { ns_name, value } = attribute {
Some((ns_name, value)) Some((ns_name, value))
@ -296,53 +281,24 @@ impl<R> Reader<R> {
} }
xml::NSAttName::DefaultAttName => None, xml::NSAttName::DefaultAttName => None,
}; };
let namespace = NamespaceDeclaration { let namespace = Namespace {
prefix, prefix,
namespace: namespace.process()?, namespace: namespace.process()?,
}; };
if !element_namespace_declarations.insert(namespace.clone()) { if !namespace_declarations.insert(namespace.clone()) {
return Err(Error::DuplicateNameSpaceDeclaration(namespace)); return Err(Error::DuplicateNameSpace(namespace));
} }
} }
// all namespaces available in the element scope (from both parent elements and element itself) // all namespaces available to the element (from both parent elements and element itself)
let namespace_declarations_stack: Vec<&NamespaceDeclaration> = namespace_declarations let namespace_stack: Vec<&Namespace> = namespaces
.iter() .iter()
.flatten() .flatten()
.chain(element_namespace_declarations.iter()) .chain(namespace_declarations.iter())
.collect(); .collect();
// element name and default attribute namespace
let element_namespace_declaration;
let element_local_name = s_tag.name.local_part().to_string();
match s_tag.name.prefix() {
Some(prefix) => {
element_namespace_declaration = namespace_declarations_stack
.iter()
.rfind(|namespace| namespace.prefix.as_deref() == Some(prefix));
}
None => {
element_namespace_declaration = namespace_declarations_stack
.iter()
.rfind(|namespace| namespace.prefix == None);
}
}
let element_default_namespace = element_namespace_declaration
.ok_or_else(|| Error::UnqualifiedNamespace(s_tag.name.to_string()))?
.namespace
.clone();
let element_name = Name {
namespace: element_default_namespace,
local_name: element_local_name,
};
// attributes
let mut attributes = HashMap::new(); let mut attributes = HashMap::new();
for (q_name, value) in s_tag.attributes.iter().filter_map(|attribute| { for (q_name, value) in s_tag.attributes.iter().filter_map(|attribute| {
if let xml::Attribute::Attribute { name, value } = attribute { if let xml::Attribute::Attribute { name, value } = attribute {
Some((name, value)) Some((name, value))
@ -350,26 +306,29 @@ impl<R> Reader<R> {
None None
} }
}) { }) {
let attribute_namespace_declaration; let namespace;
let attribute_local_name = q_name.local_part().to_string(); let attribute_name;
match q_name.prefix() { match q_name {
Some(prefix) => { xml::QName::PrefixedName(prefixed_name) => {
attribute_namespace_declaration = namespace = namespace_stack.iter().rfind(|namespace| {
namespace_declarations_stack namespace.prefix.as_deref() == Some(**prefixed_name.prefix)
.iter() });
.rfind(|namespace_declaration| { attribute_name = prefixed_name.local_part.to_string();
namespace_declaration.prefix.as_deref() == Some(prefix) }
}); xml::QName::UnprefixedName(unprefixed_name) => {
namespace = namespace_stack
.iter()
.rfind(|namespace| namespace.prefix == None);
attribute_name = unprefixed_name.to_string();
} }
None => attribute_namespace_declaration = element_namespace_declaration,
} }
if let Some(namespace_declaration) = attribute_namespace_declaration { if let Some(namespace) = namespace {
let namespace = (*namespace).clone();
let name = Name { let name = Name {
namespace: namespace_declaration.namespace.clone(), namespace,
local_name: attribute_local_name, name: attribute_name,
}; };
let value = value.process()?; let value = value.process()?;
// check for duplicate attribute
if let Some(_value) = attributes.insert(name, value) { if let Some(_value) = attributes.insert(name, value) {
return Err(Error::DuplicateAttribute(q_name.to_string())); return Err(Error::DuplicateAttribute(q_name.to_string()));
} }
@ -378,13 +337,36 @@ impl<R> Reader<R> {
} }
} }
depth.push(element_name.clone()); let name;
let namespace;
match &s_tag.name {
xml::QName::PrefixedName(prefixed_name) => {
namespace = namespace_stack
.iter()
.rfind(|namespace| namespace.prefix.as_deref() == Some(**prefixed_name.prefix));
name = prefixed_name.local_part.to_string();
}
xml::QName::UnprefixedName(unprefixed_name) => {
namespace = namespace_stack
.iter()
.rfind(|namespace| namespace.prefix == None);
name = unprefixed_name.to_string();
}
}
namespace_declarations.push(element_namespace_declarations.clone()); let namespace = (*namespace
.ok_or_else(|| Error::UnqualifiedNamespace(s_tag.name.to_string()))?)
.clone();
let name = Name { namespace, name };
depth.push(name.clone());
namespaces.push(namespace_declarations.clone());
return Ok(Element { return Ok(Element {
name: element_name, name,
namespace_declarations: element_namespace_declarations, namespace_decl: namespace_declarations,
attributes, attributes,
content: Vec::new(), content: Vec::new(),
}); });
@ -392,234 +374,257 @@ impl<R> Reader<R> {
fn end_tag_from_xml( fn end_tag_from_xml(
depth: &mut Vec<Name>, depth: &mut Vec<Name>,
namespace_declarations: &mut Vec<HashSet<NamespaceDeclaration>>, namespaces: &mut Vec<HashSet<Namespace>>,
xml_e_tag: xml::ETag, e_tag: xml::ETag,
) -> Result<()> { ) -> Result<()> {
if let Some(s_tag_name) = depth.pop() { if let Some(s_tag_name) = depth.pop() {
let e_tag_namespace_declaration; if s_tag_name.namespace.prefix.as_deref() == e_tag.name.prefix()
let e_tag_local_name = xml_e_tag.name.local_part().to_string(); && s_tag_name.name == e_tag.name.local_part()
let namespace_declarations_stack: Vec<_> = {
namespace_declarations.iter().flatten().collect(); namespaces.pop();
match xml_e_tag.name.prefix() {
Some(prefix) => {
e_tag_namespace_declaration = namespace_declarations_stack
.iter()
.rfind(|namespace| namespace.prefix.as_deref() == Some(prefix));
}
None => {
e_tag_namespace_declaration = namespace_declarations_stack
.iter()
.rfind(|namespace| namespace.prefix == None);
}
}
let e_tag_namespace = e_tag_namespace_declaration
.ok_or_else(|| Error::UnqualifiedNamespace(xml_e_tag.name.to_string()))?
.namespace
.clone();
let e_tag_name = Name {
namespace: e_tag_namespace,
local_name: e_tag_local_name,
};
if e_tag_name != s_tag_name {
return Err(Error::MismatchedEndTag(s_tag_name, e_tag_name));
}
if s_tag_name == e_tag_name {
namespace_declarations.pop();
return Ok(()); return Ok(());
} else { } else {
return Err(Error::MismatchedEndTag(s_tag_name, e_tag_name)); return Err(Error::MismatchedEndTag(
s_tag_name.name,
e_tag.name.to_string(),
));
} }
} else { } else {
return Err(Error::NotInElement(xml_e_tag.name.to_string())); return Err(Error::NotInElement(e_tag.name.to_string()));
} }
} }
fn element_from_xml( fn element_from_xml(
namespace_declarations: &mut Vec<HashSet<NamespaceDeclaration>>, namespaces: &mut Vec<HashSet<Namespace>>,
element: xml::Element, element: xml::Element,
) -> Result<Element> { ) -> Result<Element> {
let xml_name;
let xml_attributes;
let xml_content;
let xml_e_name;
match element { match element {
xml::Element::Empty(empty_elem_tag) => { xml::Element::Empty(empty_elem_tag) => {
xml_name = empty_elem_tag.name; let mut namespace_declarations = HashSet::new();
xml_attributes = empty_elem_tag.attributes; for (prefix, namespace) in
xml_content = None; empty_elem_tag.attributes.iter().filter_map(|attribute| {
xml_e_name = None; if let xml::Attribute::NamespaceDeclaration { ns_name, value } = attribute {
} Some((ns_name, value))
xml::Element::NotEmpty(s_tag, content, e_tag) => { } else {
xml_name = s_tag.name; None
xml_attributes = s_tag.attributes; }
xml_content = Some(content); })
xml_e_name = Some(e_tag.name); {
} let prefix = match prefix {
} xml::NSAttName::PrefixedAttName(prefixed_att_name) => {
Some(prefixed_att_name.to_string())
// namespace declarations on element }
xml::NSAttName::DefaultAttName => None,
let mut element_namespace_declarations = HashSet::new(); };
for (prefix, namespace) in xml_attributes.iter().filter_map(|attribute| { let namespace = Namespace {
if let xml::Attribute::NamespaceDeclaration { ns_name, value } = attribute { prefix,
Some((ns_name, value)) namespace: namespace.process()?,
} else { };
None if !namespace_declarations.insert(namespace.clone()) {
} return Err(Error::DuplicateNameSpace(namespace));
}) { }
let prefix = match prefix {
xml::NSAttName::PrefixedAttName(prefixed_att_name) => {
Some(prefixed_att_name.to_string())
} }
xml::NSAttName::DefaultAttName => None,
};
let namespace = NamespaceDeclaration {
prefix,
namespace: namespace.process()?,
};
if !element_namespace_declarations.insert(namespace.clone()) {
return Err(Error::DuplicateNameSpaceDeclaration(namespace));
}
}
// all namespaces available in the element scope (from both parent elements and element itself) // all namespaces available to the element (from both parent elements and element itself)
let namespace_declarations_stack: Vec<&NamespaceDeclaration> = namespace_declarations let namespace_stack: Vec<&Namespace> = namespaces
.iter()
.flatten()
.chain(element_namespace_declarations.iter())
.collect();
// element name and default attribute namespace
let element_namespace_declaration;
let element_local_name = xml_name.local_part().to_string();
match xml_name.prefix() {
Some(prefix) => {
element_namespace_declaration = namespace_declarations_stack
.iter() .iter()
.rfind(|namespace| namespace.prefix.as_deref() == Some(prefix)); .flatten()
} .chain(namespace_declarations.iter())
None => { .collect();
element_namespace_declaration = namespace_declarations_stack
.iter()
.rfind(|namespace| namespace.prefix == None);
}
}
let element_default_namespace = element_namespace_declaration let mut attributes = HashMap::new();
.ok_or_else(|| Error::UnqualifiedNamespace(xml_name.to_string()))?
.namespace
.clone();
let element_name = Name { for (q_name, value) in empty_elem_tag.attributes.iter().filter_map(|attribute| {
namespace: element_default_namespace, if let xml::Attribute::Attribute { name, value } = attribute {
local_name: element_local_name, Some((name, value))
}; } else {
None
// end tag name match check }
}) {
if let Some(xml_e_name) = xml_e_name { let namespace;
let e_tag_namespace_declaration; let attribute_name;
let e_tag_local_name = xml_e_name.local_part().to_string(); match q_name {
xml::QName::PrefixedName(prefixed_name) => {
match xml_e_name.prefix() { namespace = namespace_stack.iter().rfind(|namespace| {
Some(prefix) => { namespace.prefix.as_deref() == Some(**prefixed_name.prefix)
e_tag_namespace_declaration = namespace_declarations_stack });
.iter() attribute_name = prefixed_name.local_part.to_string();
.rfind(|namespace| namespace.prefix.as_deref() == Some(prefix)); }
xml::QName::UnprefixedName(unprefixed_name) => {
namespace = namespace_stack
.iter()
.rfind(|namespace| namespace.prefix == None);
attribute_name = unprefixed_name.to_string();
}
}
if let Some(namespace) = namespace {
let namespace = (*namespace).clone();
let name = Name {
namespace,
name: attribute_name,
};
let value = value.process()?;
if let Some(_value) = attributes.insert(name, value) {
return Err(Error::DuplicateAttribute(q_name.to_string()));
}
} else {
return Err(Error::UnqualifiedNamespace(q_name.to_string()));
}
} }
None => {
e_tag_namespace_declaration = namespace_declarations_stack
.iter()
.rfind(|namespace| namespace.prefix == None);
}
}
let e_tag_namespace = e_tag_namespace_declaration let name;
.ok_or_else(|| Error::UnqualifiedNamespace(xml_name.to_string()))? let namespace;
.namespace match &empty_elem_tag.name {
xml::QName::PrefixedName(prefixed_name) => {
namespace = namespace_stack.iter().rfind(|namespace| {
namespace.prefix.as_deref() == Some(**prefixed_name.prefix)
});
name = prefixed_name.local_part.to_string();
}
xml::QName::UnprefixedName(unprefixed_name) => {
namespace = namespace_stack
.iter()
.rfind(|namespace| namespace.prefix == None);
name = unprefixed_name.to_string();
}
}
let namespace = (*namespace
.ok_or_else(|| Error::UnqualifiedNamespace(empty_elem_tag.name.to_string()))?)
.clone(); .clone();
let e_tag_name = Name { let name = Name { namespace, name };
namespace: e_tag_namespace,
local_name: e_tag_local_name,
};
if e_tag_name != element_name { return Ok(Element {
return Err(Error::MismatchedEndTag(element_name, e_tag_name)); name,
namespace_decl: namespace_declarations,
attributes,
content: Vec::new(),
});
} }
} xml::Element::NotEmpty(s_tag, content, e_tag) => {
if s_tag.name != e_tag.name {
return Err(Error::MismatchedEndTag(
s_tag.name.to_string(),
e_tag.name.to_string(),
));
}
let mut namespace_declarations = HashSet::new();
for (prefix, namespace) in s_tag.attributes.iter().filter_map(|attribute| {
if let xml::Attribute::NamespaceDeclaration { ns_name, value } = attribute {
Some((ns_name, value))
} else {
None
}
}) {
let prefix = match prefix {
xml::NSAttName::PrefixedAttName(prefixed_att_name) => {
Some(prefixed_att_name.to_string())
}
xml::NSAttName::DefaultAttName => None,
};
let namespace = Namespace {
prefix,
namespace: namespace.process()?,
};
if !namespace_declarations.insert(namespace.clone()) {
return Err(Error::DuplicateNameSpace(namespace));
}
}
// attributes // all namespaces available to the element (from both parent elements and element itself)
let namespace_stack: Vec<&Namespace> = namespaces
.iter()
.flatten()
.chain(namespace_declarations.iter())
.collect();
let mut attributes = HashMap::new(); let mut attributes = HashMap::new();
for (q_name, value) in xml_attributes.iter().filter_map(|attribute| {
if let xml::Attribute::Attribute { name, value } = attribute { for (q_name, value) in s_tag.attributes.iter().filter_map(|attribute| {
Some((name, value)) if let xml::Attribute::Attribute { name, value } = attribute {
} else { Some((name, value))
None } else {
} None
}) { }
let attribute_namespace_declaration; }) {
let attribute_local_name = q_name.local_part().to_string(); let namespace;
match q_name.prefix() { let attribute_name;
Some(prefix) => { match q_name {
attribute_namespace_declaration = xml::QName::PrefixedName(prefixed_name) => {
namespace_declarations_stack namespace = namespace_stack.iter().rfind(|namespace| {
.iter() namespace.prefix.as_deref() == Some(**prefixed_name.prefix)
.rfind(|namespace_declaration| {
namespace_declaration.prefix.as_deref() == Some(prefix)
}); });
attribute_name = prefixed_name.local_part.to_string();
}
xml::QName::UnprefixedName(unprefixed_name) => {
namespace = namespace_stack
.iter()
.rfind(|namespace| namespace.prefix == None);
attribute_name = unprefixed_name.to_string();
}
}
if let Some(namespace) = namespace {
let namespace = (*namespace).clone();
let name = Name {
namespace,
name: attribute_name,
};
let value = value.process()?;
if let Some(_value) = attributes.insert(name, value) {
return Err(Error::DuplicateAttribute(q_name.to_string()));
}
} else {
return Err(Error::UnqualifiedNamespace(q_name.to_string()));
}
} }
None => attribute_namespace_declaration = element_namespace_declaration,
} let name;
if let Some(namespace_declaration) = attribute_namespace_declaration { let namespace;
let name = Name { match &s_tag.name {
namespace: namespace_declaration.namespace.clone(), xml::QName::PrefixedName(prefixed_name) => {
local_name: attribute_local_name, namespace = namespace_stack.iter().rfind(|namespace| {
}; namespace.prefix.as_deref() == Some(**prefixed_name.prefix)
let value = value.process()?; });
// check for duplicate attribute name = prefixed_name.local_part.to_string();
if let Some(_value) = attributes.insert(name, value) { }
return Err(Error::DuplicateAttribute(q_name.to_string())); xml::QName::UnprefixedName(unprefixed_name) => {
namespace = namespace_stack
.iter()
.rfind(|namespace| namespace.prefix == None);
name = unprefixed_name.to_string();
}
} }
} else {
return Err(Error::UnqualifiedNamespace(q_name.to_string())); let namespace = (*namespace
.ok_or_else(|| Error::UnqualifiedNamespace(s_tag.name.to_string()))?)
.clone();
let name = Name { namespace, name };
namespaces.push(namespace_declarations.clone());
let content = Self::content_from_xml(namespaces, content)?;
namespaces.pop();
return Ok(Element {
name,
namespace_decl: namespace_declarations,
attributes,
content,
});
} }
} }
let content;
if let Some(xml_content) = xml_content {
namespace_declarations.push(element_namespace_declarations.clone());
content = Self::content_from_xml(namespace_declarations, xml_content)?;
namespace_declarations.pop();
} else {
content = Vec::new();
}
return Ok(Element {
name: element_name,
namespace_declarations: element_namespace_declarations,
attributes,
content,
});
} }
fn content_from_xml( fn content_from_xml(
namespaces: &mut Vec<HashSet<NamespaceDeclaration>>, namespaces: &mut Vec<HashSet<Namespace>>,
xml_content: xml::Content, element: xml::Content,
) -> Result<Vec<Content>> { ) -> Result<Vec<Content>> {
let mut content = Vec::new(); let mut content = Vec::new();
let mut text = xml_content.char_data.map(|str| String::from(*str)); let mut text = element.char_data.map(|str| String::from(*str));
for (content_item, char_data) in xml_content.content { for (content_item, char_data) in element.content {
match content_item { match content_item {
xml::ContentItem::Element(element) => { xml::ContentItem::Element(element) => {
text.map(|text| content.push(Content::Text(text))); text.map(|text| content.push(Content::Text(text)));

View File

@ -1,53 +1,26 @@
use std::collections::HashSet; use futures::{AsyncWrite, Sink};
use futures::Sink;
use tokio::io::AsyncWrite;
use crate::{ use crate::{
element::{Element, Name, NamespaceDeclaration}, element::{Element, Name, Namespace},
error::Error, error::Error,
xml::{self, composers::Composer, parsers_complete::Parser, ETag},
}; };
// pub struct Writer<W, C = Composer> { // pub struct Writer<W, C = Composer> {
pub struct Writer<W> { pub struct Writer<W> {
inner: W, writer: W,
depth: Vec<Name>, depth: Vec<Name>,
namespaces: Vec<HashSet<NamespaceDeclaration>>, namespaces: Vec<(usize, Namespace)>,
} }
impl<W: AsyncWrite + Unpin> Writer<W> { impl<W: AsyncWrite> Writer<W> {
pub async fn write(&mut self, element: Element) -> Result<(), Error> { pub async fn write(&self, element: impl Into<Element>) -> Result<(), Error> {
todo!() todo!()
} }
pub async fn write_start(&self, element: impl Into<Element>) -> Result<(), Error> {
pub async fn write_start(&mut self, element: Element) -> Result<(), Error> {
todo!() todo!()
} }
pub async fn write_end(&self) -> Result<(), Error> {
pub async fn write_end(&mut self) -> Result<(), Error> {
todo!() todo!()
// let e_tag;
// if let Some(name) = self.depth.pop() {
// if let Some(prefix) = name.namespace.prefix {
// e_tag = xml::ETag {
// name: xml::QName::PrefixedName(xml::PrefixedName {
// prefix: xml::Prefix::parse_full(&prefix)?,
// local_part: xml::LocalPart::parse_full(&name.name)?,
// }),
// };
// e_tag.write(&mut self.inner).await?;
// Ok(())
// } else {
// e_tag = xml::ETag {
// name: xml::QName::UnprefixedName(xml::UnprefixedName::parse_full(&name.name)?),
// };
// e_tag.write(&mut self.inner).await?;
// Ok(())
// }
// } else {
// return Err(Error::NotInElement("".to_string()));
// }
} }
} }

View File

@ -30,19 +30,6 @@ pub trait Parser<'s> {
type Output; type Output;
fn parse(input: &'s str) -> IResult<&str, Self::Output>; fn parse(input: &'s str) -> IResult<&str, Self::Output>;
fn parse_full(input: &'s str) -> crate::Result<Self::Output> {
match <Self as Parser>::parse(input) {
Ok((rest, output)) => {
if rest.is_empty() {
return Ok(output);
} else {
return Err(crate::error::Error::ExtraData(rest.to_string()));
}
}
Result::Err(e) => return Err(crate::error::Error::ParseError(e.to_string())),
}
}
} }
/// [1] NSAttName ::= PrefixedAttName | DefaultAttName /// [1] NSAttName ::= PrefixedAttName | DefaultAttName