Compare commits

...

3 Commits

Author SHA1 Message Date
cel 🌸 caf8b7506e implement end tag match check 2024-11-19 16:26:59 +00:00
cel 🌸 c2a84072ac fix attribute namespace resolution 2024-11-19 16:07:34 +00:00
cel 🌸 c8ed16a2d1 store only namespace name in qualified name, not namespace declaration 2024-11-19 14:52:14 +00:00
5 changed files with 344 additions and 308 deletions

View File

@ -10,7 +10,7 @@ use crate::{
// when are namespaces names chosen then if they are automatically calculated
// namespaces are held by readers and writers.
#[derive(PartialEq, Eq, Hash, Clone, Debug)]
pub struct Namespace {
pub struct NamespaceDeclaration {
pub prefix: Option<String>,
pub namespace: String,
}
@ -18,8 +18,8 @@ pub struct Namespace {
// names are qualified, they contain a reference to the namespace (held within the reader/writer)
#[derive(PartialEq, Eq, Hash, Clone, Debug)]
pub struct Name {
pub namespace: Namespace,
pub name: String,
pub namespace: String,
pub local_name: String,
}
#[derive(Debug)]
@ -40,7 +40,7 @@ pub struct Element {
// namespace: String,
// 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.
pub namespace_decl: HashSet<Namespace>,
pub namespace_declarations: HashSet<NamespaceDeclaration>,
// 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
// 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 crate::element::{Name, Namespace};
use crate::element::{Name, NamespaceDeclaration};
#[derive(Debug)]
pub enum Error {
@ -10,11 +10,12 @@ pub enum Error {
EntityProcessError(String),
// TODO: better choice for failures than string
InvalidCharRef(String),
DuplicateNameSpace(Namespace),
DuplicateNameSpaceDeclaration(NamespaceDeclaration),
DuplicateAttribute(String),
UnqualifiedNamespace(String),
MismatchedEndTag(String, String),
MismatchedEndTag(Name, Name),
NotInElement(String),
ExtraData(String),
}
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;
use crate::{
element::{Content, Element, Name, Namespace},
element::{Content, Element, Name, NamespaceDeclaration},
error::Error,
xml::{self, parsers::Parser},
Result,
@ -26,7 +26,7 @@ pub struct Reader<R> {
// holds which tags we are in atm over depth
// to have names reference namespaces could
depth: Vec<Name>,
namespaces: Vec<HashSet<Namespace>>,
namespace_declarations: Vec<HashSet<NamespaceDeclaration>>,
}
impl<R> Reader<R> {
@ -35,7 +35,7 @@ impl<R> Reader<R> {
inner: reader,
buffer: Buffer::with_capacity(MAX_STANZA_SIZE),
depth: Vec::new(),
namespaces: Vec::new(),
namespace_declarations: Vec::new(),
}
}
}
@ -75,8 +75,11 @@ where
match xml::STag::parse(input) {
Ok((rest, e)) => {
let len = self.buffer.available_data() - rest.as_bytes().len();
let element =
Reader::<R>::start_tag_from_xml(&mut self.depth, &mut self.namespaces, e)?;
let element = Reader::<R>::start_tag_from_xml(
&mut self.depth,
&mut self.namespace_declarations,
e,
)?;
self.buffer.consume(len);
return Ok(element);
}
@ -97,7 +100,11 @@ where
match xml::ETag::parse(input) {
Ok((rest, e)) => {
let len = self.buffer.available_data() - rest.as_bytes().len();
Reader::<R>::end_tag_from_xml(&mut self.depth, &mut self.namespaces, e)?;
Reader::<R>::end_tag_from_xml(
&mut self.depth,
&mut self.namespace_declarations,
e,
)?;
self.buffer.consume(len);
return Ok(());
}
@ -118,7 +125,8 @@ where
match xml::Element::parse(input) {
Ok((rest, e)) => {
let len = self.buffer.available_data() - rest.as_bytes().len();
let element = Reader::<R>::element_from_xml(&mut self.namespaces, e)?;
let element =
Reader::<R>::element_from_xml(&mut self.namespace_declarations, e)?;
self.buffer.consume(len);
return Ok(element);
}
@ -156,8 +164,10 @@ where
} else {
let len =
self.buffer.available_data() - rest.as_bytes().len();
let element =
Self::element_from_xml(&mut self.namespaces, element)?;
let element = Self::element_from_xml(
&mut self.namespace_declarations,
element,
)?;
self.buffer.consume(len);
return Ok(Content::Element(element));
}
@ -209,12 +219,15 @@ where
match xml::ContentItem::parse(input) {
Ok((rest, content_item)) => match content_item {
xml::ContentItem::Element(element) => {
// text can still be empty
if !text.is_empty() {
return Ok(Content::Text(text));
} else {
let len = self.buffer.available_data() - rest.as_bytes().len();
let element =
Self::element_from_xml(&mut self.namespaces, element)?;
let element = Self::element_from_xml(
&mut self.namespace_declarations,
element,
)?;
self.buffer.consume(len);
return Ok(Content::Element(element));
}
@ -264,10 +277,12 @@ where
impl<R> Reader<R> {
fn start_tag_from_xml(
depth: &mut Vec<Name>,
namespaces: &mut Vec<HashSet<Namespace>>,
namespace_declarations: &mut Vec<HashSet<NamespaceDeclaration>>,
s_tag: xml::STag,
) -> Result<Element> {
let mut namespace_declarations = HashSet::new();
// namespace declarations on element
let mut element_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))
@ -281,24 +296,53 @@ impl<R> Reader<R> {
}
xml::NSAttName::DefaultAttName => None,
};
let namespace = Namespace {
let namespace = NamespaceDeclaration {
prefix,
namespace: namespace.process()?,
};
if !namespace_declarations.insert(namespace.clone()) {
return Err(Error::DuplicateNameSpace(namespace));
if !element_namespace_declarations.insert(namespace.clone()) {
return Err(Error::DuplicateNameSpaceDeclaration(namespace));
}
}
// all namespaces available to the element (from both parent elements and element itself)
let namespace_stack: Vec<&Namespace> = namespaces
// all namespaces available in the element scope (from both parent elements and element itself)
let namespace_declarations_stack: Vec<&NamespaceDeclaration> = namespace_declarations
.iter()
.flatten()
.chain(namespace_declarations.iter())
.chain(element_namespace_declarations.iter())
.collect();
let mut attributes = HashMap::new();
// 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();
for (q_name, value) in s_tag.attributes.iter().filter_map(|attribute| {
if let xml::Attribute::Attribute { name, value } = attribute {
Some((name, value))
@ -306,29 +350,26 @@ impl<R> Reader<R> {
None
}
}) {
let namespace;
let attribute_name;
match q_name {
xml::QName::PrefixedName(prefixed_name) => {
namespace = namespace_stack.iter().rfind(|namespace| {
namespace.prefix.as_deref() == Some(**prefixed_name.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();
let attribute_namespace_declaration;
let attribute_local_name = q_name.local_part().to_string();
match q_name.prefix() {
Some(prefix) => {
attribute_namespace_declaration =
namespace_declarations_stack
.iter()
.rfind(|namespace_declaration| {
namespace_declaration.prefix.as_deref() == Some(prefix)
});
}
None => attribute_namespace_declaration = element_namespace_declaration,
}
if let Some(namespace) = namespace {
let namespace = (*namespace).clone();
if let Some(namespace_declaration) = attribute_namespace_declaration {
let name = Name {
namespace,
name: attribute_name,
namespace: namespace_declaration.namespace.clone(),
local_name: attribute_local_name,
};
let value = value.process()?;
// check for duplicate attribute
if let Some(_value) = attributes.insert(name, value) {
return Err(Error::DuplicateAttribute(q_name.to_string()));
}
@ -337,36 +378,13 @@ impl<R> Reader<R> {
}
}
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();
}
}
depth.push(element_name.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());
namespace_declarations.push(element_namespace_declarations.clone());
return Ok(Element {
name,
namespace_decl: namespace_declarations,
name: element_name,
namespace_declarations: element_namespace_declarations,
attributes,
content: Vec::new(),
});
@ -374,257 +392,234 @@ impl<R> Reader<R> {
fn end_tag_from_xml(
depth: &mut Vec<Name>,
namespaces: &mut Vec<HashSet<Namespace>>,
e_tag: xml::ETag,
namespace_declarations: &mut Vec<HashSet<NamespaceDeclaration>>,
xml_e_tag: xml::ETag,
) -> Result<()> {
if let Some(s_tag_name) = depth.pop() {
if s_tag_name.namespace.prefix.as_deref() == e_tag.name.prefix()
&& s_tag_name.name == e_tag.name.local_part()
{
namespaces.pop();
let e_tag_namespace_declaration;
let e_tag_local_name = xml_e_tag.name.local_part().to_string();
let namespace_declarations_stack: Vec<_> =
namespace_declarations.iter().flatten().collect();
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(());
} else {
return Err(Error::MismatchedEndTag(
s_tag_name.name,
e_tag.name.to_string(),
));
return Err(Error::MismatchedEndTag(s_tag_name, e_tag_name));
}
} else {
return Err(Error::NotInElement(e_tag.name.to_string()));
return Err(Error::NotInElement(xml_e_tag.name.to_string()));
}
}
fn element_from_xml(
namespaces: &mut Vec<HashSet<Namespace>>,
namespace_declarations: &mut Vec<HashSet<NamespaceDeclaration>>,
element: xml::Element,
) -> Result<Element> {
let xml_name;
let xml_attributes;
let xml_content;
let xml_e_name;
match element {
xml::Element::Empty(empty_elem_tag) => {
let mut namespace_declarations = HashSet::new();
for (prefix, namespace) in
empty_elem_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));
}
}
// 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();
for (q_name, value) in empty_elem_tag.attributes.iter().filter_map(|attribute| {
if let xml::Attribute::Attribute { name, value } = attribute {
Some((name, value))
} else {
None
}
}) {
let namespace;
let attribute_name;
match q_name {
xml::QName::PrefixedName(prefixed_name) => {
namespace = namespace_stack.iter().rfind(|namespace| {
namespace.prefix.as_deref() == Some(**prefixed_name.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()));
}
}
let name;
let 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();
let name = Name { namespace, name };
return Ok(Element {
name,
namespace_decl: namespace_declarations,
attributes,
content: Vec::new(),
});
xml_name = empty_elem_tag.name;
xml_attributes = empty_elem_tag.attributes;
xml_content = None;
xml_e_name = None;
}
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));
}
}
// 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();
for (q_name, value) in s_tag.attributes.iter().filter_map(|attribute| {
if let xml::Attribute::Attribute { name, value } = attribute {
Some((name, value))
} else {
None
}
}) {
let namespace;
let attribute_name;
match q_name {
xml::QName::PrefixedName(prefixed_name) => {
namespace = namespace_stack.iter().rfind(|namespace| {
namespace.prefix.as_deref() == Some(**prefixed_name.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()));
}
}
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();
}
}
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,
});
xml_name = s_tag.name;
xml_attributes = s_tag.attributes;
xml_content = Some(content);
xml_e_name = Some(e_tag.name);
}
}
// namespace declarations on element
let mut element_namespace_declarations = HashSet::new();
for (prefix, namespace) in xml_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 = 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)
let namespace_declarations_stack: Vec<&NamespaceDeclaration> = namespace_declarations
.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()
.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(xml_name.to_string()))?
.namespace
.clone();
let element_name = Name {
namespace: element_default_namespace,
local_name: element_local_name,
};
// end tag name match check
if let Some(xml_e_name) = xml_e_name {
let e_tag_namespace_declaration;
let e_tag_local_name = xml_e_name.local_part().to_string();
match xml_e_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_name.to_string()))?
.namespace
.clone();
let e_tag_name = Name {
namespace: e_tag_namespace,
local_name: e_tag_local_name,
};
if e_tag_name != element_name {
return Err(Error::MismatchedEndTag(element_name, e_tag_name));
}
}
// attributes
let mut attributes = HashMap::new();
for (q_name, value) in xml_attributes.iter().filter_map(|attribute| {
if let xml::Attribute::Attribute { name, value } = attribute {
Some((name, value))
} else {
None
}
}) {
let attribute_namespace_declaration;
let attribute_local_name = q_name.local_part().to_string();
match q_name.prefix() {
Some(prefix) => {
attribute_namespace_declaration =
namespace_declarations_stack
.iter()
.rfind(|namespace_declaration| {
namespace_declaration.prefix.as_deref() == Some(prefix)
});
}
None => attribute_namespace_declaration = element_namespace_declaration,
}
if let Some(namespace_declaration) = attribute_namespace_declaration {
let name = Name {
namespace: namespace_declaration.namespace.clone(),
local_name: attribute_local_name,
};
let value = value.process()?;
// check for duplicate attribute
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()));
}
}
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(
namespaces: &mut Vec<HashSet<Namespace>>,
element: xml::Content,
namespaces: &mut Vec<HashSet<NamespaceDeclaration>>,
xml_content: xml::Content,
) -> Result<Vec<Content>> {
let mut content = Vec::new();
let mut text = element.char_data.map(|str| String::from(*str));
for (content_item, char_data) in element.content {
let mut text = xml_content.char_data.map(|str| String::from(*str));
for (content_item, char_data) in xml_content.content {
match content_item {
xml::ContentItem::Element(element) => {
text.map(|text| content.push(Content::Text(text)));

View File

@ -1,26 +1,53 @@
use futures::{AsyncWrite, Sink};
use std::collections::HashSet;
use futures::Sink;
use tokio::io::AsyncWrite;
use crate::{
element::{Element, Name, Namespace},
element::{Element, Name, NamespaceDeclaration},
error::Error,
xml::{self, composers::Composer, parsers_complete::Parser, ETag},
};
// pub struct Writer<W, C = Composer> {
pub struct Writer<W> {
writer: W,
inner: W,
depth: Vec<Name>,
namespaces: Vec<(usize, Namespace)>,
namespaces: Vec<HashSet<NamespaceDeclaration>>,
}
impl<W: AsyncWrite> Writer<W> {
pub async fn write(&self, element: impl Into<Element>) -> Result<(), Error> {
impl<W: AsyncWrite + Unpin> Writer<W> {
pub async fn write(&mut self, element: Element) -> Result<(), Error> {
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!()
}
pub async fn write_end(&self) -> Result<(), Error> {
pub async fn write_end(&mut self) -> Result<(), Error> {
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,6 +30,19 @@ pub trait Parser<'s> {
type 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