WIP: refactor Element type - namespace work

This commit is contained in:
cel 🌸 2023-08-05 20:14:09 +01:00
parent dec6f0105d
commit 5334cd4ed6
3 changed files with 272 additions and 167 deletions

View File

@ -5,7 +5,7 @@ use rsasl::mechname::MechanismNameError;
use crate::{ use crate::{
jid::ParseError, jid::ParseError,
stanza::{self, ElementError}, stanza::{self, ElementError, ElementParseError},
}; };
#[derive(Debug)] #[derive(Debug)]
@ -22,6 +22,7 @@ pub enum JabberError {
NoType, NoType,
IDMismatch, IDMismatch,
BindError, BindError,
ElementParse(ElementParseError),
ParseError, ParseError,
UnexpectedEnd, UnexpectedEnd,
UnexpectedElement, UnexpectedElement,
@ -87,3 +88,9 @@ impl From<ParseError> for JabberError {
Self::JID(e) Self::JID(e)
} }
} }
impl From<ElementParseError> for JabberError {
fn from(e: ElementParseError) -> Self {
Self::ElementParse(e)
}
}

View File

@ -1,10 +1,12 @@
use std::collections::BTreeMap;
use quick_xml::{ use quick_xml::{
events::{BytesStart, BytesText, Event}, events::{BytesStart, BytesText, Event},
name::QName, name::QName,
Reader, Reader,
}; };
use super::{Element, IntoElement}; use super::{Element, IntoElement, Node};
use crate::{JabberError, JID}; use crate::{JabberError, JID};
const XMLNS: &str = "urn:ietf:params:xml:ns:xmpp-bind"; const XMLNS: &str = "urn:ietf:params:xml:ns:xmpp-bind";
@ -14,7 +16,30 @@ pub struct Bind {
pub jid: Option<JID>, pub jid: Option<JID>,
} }
impl<'e> IntoElement<'e> for Bind { impl From<Bind> for Element {
fn from(value: Bind) -> Self {
let mut namespace_declarations = Box::new(BTreeMap::new());
namespace_declarations.insert(None, XMLNS.to_owned());
let mut children = Vec::new();
if let Some(resource) = value.resource {
children.push(Node::Element(
Element { prefix: None, localname: "", namespace: , namespace_declarations: , attributes: , children: }
)
)
}
Self {
prefix: None,
localname: "bind".to_string(),
namespace: XMLNS.to_owned(),
namespace_declarations,
attributes: todo!(),
children: todo!(),
}
}
}
impl IntoElement for Bind {
fn event(&self) -> quick_xml::events::Event<'static> { fn event(&self) -> quick_xml::events::Event<'static> {
let mut bind_event = BytesStart::new("bind"); let mut bind_event = BytesStart::new("bind");
bind_event.push_attribute(("xmlns", XMLNS)); bind_event.push_attribute(("xmlns", XMLNS));

View File

@ -17,23 +17,17 @@ use tokio::io::{AsyncBufRead, AsyncWrite};
use crate::{JabberError, Result}; use crate::{JabberError, Result};
// #[derive(Clone, Debug)]
// pub struct EventTree<'e> {
// pub event: Event<'e>,
// pub children: Option<Vec<Element<'e>>>,
// }
pub type Prefix<'s> = Option<&'s str>; pub type Prefix<'s> = Option<&'s str>;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
/// represents an xml element as a tree of nodes /// represents an xml element as a tree of nodes
pub struct Element<'s> { pub struct Element {
/// element prefix /// element prefix
/// e.g. `foo` in `<foo:bar />`. /// e.g. `foo` in `<foo:bar />`.
prefix: Option<&'s str>, prefix: Option<String>,
/// element name /// element name
/// e.g. `bar` in `<foo:bar />`. /// e.g. `bar` in `<foo:bar />`.
localname: &'s str, localname: String,
/// qualifying namespace /// qualifying namespace
/// an element must be qualified by a namespace /// an element must be qualified by a namespace
/// e.g. for `<stream:features>` in /// e.g. for `<stream:features>` in
@ -61,7 +55,7 @@ pub struct Element<'s> {
/// </stream:stream> /// </stream:stream>
/// ``` /// ```
/// would be `"jabber:client"` /// would be `"jabber:client"`
namespace: &'s str, namespace: String,
/// all namespaces applied to element /// all namespaces applied to element
/// e.g. for `<bind>` in /// e.g. for `<bind>` in
/// ``` /// ```
@ -75,22 +69,49 @@ pub struct Element<'s> {
/// ``` /// ```
/// would be `[(None, "urn:ietf:params:xml:ns:xmpp-bind")]` despite /// would be `[(None, "urn:ietf:params:xml:ns:xmpp-bind")]` despite
/// `(Some("stream"), "http://etherx.jabber.org/streams")` also being available /// `(Some("stream"), "http://etherx.jabber.org/streams")` also being available
namespace_declarations: Box<BTreeMap<Option<&'s str>, &'s str>>, // TODO: maybe not even needed, as can calculate when writing which namespaces need to be declared
// but then can't have unused namespace on element, confusing.
namespace_declarations: Box<BTreeMap<Option<String>, String>>,
/// element attributes /// element attributes
attributes: Box<BTreeMap<&'s str, &'s str>>, attributes: Box<BTreeMap<String, String>>,
// children elements namespaces contain their parents' namespaces // children elements namespaces contain their parents' namespaces
children: Box<Vec<Node<'s>>>, children: Box<Vec<Node>>,
}
impl Element {
pub fn new_empty<S: ToString, C: Into<Node>>(
prefix: Option<S>,
localname: S,
namespace: S,
namespace_declarations: BTreeMap<Option<S>, S>,
attributes: BTreeMap<S, S>,
children: Vec<C>,
) {
}
pub fn push_child<C: Into<Node>>(&mut self, node: C) {}
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum Node<'s> { pub enum Node {
Element(Element<'s>), Element(Element),
Text(&'s str), Text(String),
Unknown, Unknown,
} }
impl<'s> From<&Node<'s>> for Vec<Event<'s>> { impl From<Element> for Node {
fn from(node: &Node<'s>) -> Self { fn from(element: Element) -> Self {
Self::Element(element)
}
}
impl<S: ToString> From<S> for Node {
fn from(text: S) -> Self {
Self::Text(text.to_string())
}
}
impl<'s> From<&Node> for Vec<Event<'s>> {
fn from(node: &Node) -> Self {
match node { match node {
Node::Element(e) => e.into(), Node::Element(e) => e.into(),
Node::Text(t) => vec![Event::Text(BytesText::new(t))], Node::Text(t) => vec![Event::Text(BytesText::new(t))],
@ -99,7 +120,7 @@ impl<'s> From<&Node<'s>> for Vec<Event<'s>> {
} }
} }
impl<'s> Element<'s> { impl Element {
/// returns the fully qualified name /// returns the fully qualified name
/// e.g. `foo:bar` in /// e.g. `foo:bar` in
/// `<foo:bar>`. /// `<foo:bar>`.
@ -107,14 +128,14 @@ impl<'s> Element<'s> {
if let Some(prefix) = self.prefix { if let Some(prefix) = self.prefix {
format!("{}:{}", prefix, self.localname).as_str() format!("{}:{}", prefix, self.localname).as_str()
} else { } else {
self.localname &self.localname
} }
} }
/// returns the localname. /// returns the localname.
/// e.g. `bar` in `<foo:bar>` /// e.g. `bar` in `<foo:bar>`
pub fn localname(&self) -> &str { pub fn localname(&self) -> &str {
self.localname &self.localname
} }
/// returns the prefix. /// returns the prefix.
@ -130,12 +151,12 @@ impl<'s> Element<'s> {
/// `<bar:element xmlns='foo' xmlns:bar='bar'>` /// `<bar:element xmlns='foo' xmlns:bar='bar'>`
/// it will be `bar`. /// it will be `bar`.
pub fn namespace(&self) -> &str { pub fn namespace(&self) -> &str {
self.namespace &self.namespace
} }
} }
impl<'s> From<&Element<'s>> for Vec<Event<'s>> { impl<'s> From<&Element> for Vec<Event<'s>> {
fn from(element: &Element<'s>) -> Self { fn from(element: &Element) -> Self {
let name = element.name(); let name = element.name();
let event = BytesStart::new(name); let event = BytesStart::new(name);
@ -183,9 +204,9 @@ impl<'s> From<&Element<'s>> for Vec<Event<'s>> {
} }
} }
impl<'s> Element<'s> { impl Element {
/// if there is only one child in the vec of children, will return that element /// if there is only one child in the vec of children, will return that element
pub fn child(&self) -> Result<&Node<'s>> { pub fn child(&self) -> Result<&Node> {
if self.children.len() == 1 { if self.children.len() == 1 {
Ok(&self.children[0]) Ok(&self.children[0])
} else if self.children.len() > 1 { } else if self.children.len() > 1 {
@ -196,7 +217,7 @@ impl<'s> Element<'s> {
} }
/// returns reference to children /// returns reference to children
pub fn children(&self) -> Result<&Vec<Node<'s>>> { pub fn children(&self) -> Result<&Vec<Node>> {
if !self.children.is_empty() { if !self.children.is_empty() {
Ok(&self.children) Ok(&self.children)
} else { } else {
@ -206,7 +227,7 @@ impl<'s> Element<'s> {
/// returns text content, error if there is none /// returns text content, error if there is none
pub fn text_content(&self) -> Result<Vec<&str>> { pub fn text_content(&self) -> Result<Vec<&str>> {
let text = Vec::new(); let mut text = Vec::new();
for node in *self.children { for node in *self.children {
match node { match node {
Node::Text(t) => text.push(t), Node::Text(t) => text.push(t),
@ -214,23 +235,63 @@ impl<'s> Element<'s> {
} }
} }
if text.is_empty() { if text.is_empty() {
Err(ElementError::NotText) return Err(ElementError::NotText.into());
} }
Ok(text) Ok(text)
} }
pub async fn write<W: AsyncWrite + Unpin + Send>(&self, writer: &mut Writer<W>) -> Result<()> { /// returns whether or not the element is qualified by a namespace, either declared
/// by a parent, or itself.
fn namespace_qualified<S: AsRef<str>>(
&self,
local_namespaces: &BTreeMap<Option<S>, S>,
) -> bool {
if let Some(namespace) = local_namespaces.get(self.prefix) {
if namespace != self.namespace {
return false;
}
};
if let Some(namespace) = self.namespace_declarations.get(&self.prefix) {
if namespace != self.namespace {
return false;
}
}
for child in *self.children {
if child.namespace_qualified(local_namespaces) == false {
return false;
}
}
true
}
/// writes an element to a writer. the element's namespace must be qualified by the
/// context given in `local_namespaces` or the element's internal namespace declarations
pub async fn write<S: AsRef<str>, W: AsyncWrite + Unpin + Send>(
&self,
writer: &mut Writer<W>,
local_namespaces: &BTreeMap<Option<S>, S>,
) -> Result<()> {
// TODO: NEXT: instead of having a check if namespace qualified function, have the namespace declarations be added if needed given the context when converting from `Element` to `Event`s
if self.namespace_qualified(local_namespaces) {
let events: Vec<Event> = self.into(); let events: Vec<Event> = self.into();
for event in events { for event in events {
writer.write_event_async(event).await? writer.write_event_async(event).await?
} }
Ok(()) Ok(())
} else {
Err(ElementError::NamespaceNotQualified.into())
}
} }
pub async fn write_start<W: AsyncWrite + Unpin + Send>( pub async fn write_start<S: AsRef<str>, W: AsyncWrite + Unpin + Send>(
&self, &self,
writer: &mut Writer<W>, writer: &mut Writer<W>,
local_namespaces: &BTreeMap<Option<S>, S>,
) -> Result<()> { ) -> Result<()> {
if self.namespace_qualified(local_namespaces) {
let mut event = BytesStart::new(self.name()); let mut event = BytesStart::new(self.name());
// namespace declarations // namespace declarations
@ -251,6 +312,9 @@ impl<'s> Element<'s> {
writer.write_event_async(Event::Start(event)).await?; writer.write_event_async(Event::Start(event)).await?;
Ok(()) Ok(())
} else {
Err(ElementError::NamespaceNotQualified.into())
}
} }
pub async fn write_end<W: AsyncWrite + Unpin + Send>( pub async fn write_end<W: AsyncWrite + Unpin + Send>(
@ -263,9 +327,9 @@ impl<'s> Element<'s> {
} }
#[async_recursion] #[async_recursion]
pub async fn read<R: AsyncBufRead + Unpin + Send>( pub async fn read<S: AsRef<str>, R: AsyncBufRead + Unpin + Send>(
reader: &mut Reader<R>, reader: &mut Reader<R>,
local_namespaces: &BTreeMap<Option<&str>, &str>, local_namespaces: &BTreeMap<Option<S>, S>,
) -> Result<Self> { ) -> Result<Self> {
let node = Node::read_recursive(reader, local_namespaces) let node = Node::read_recursive(reader, local_namespaces)
.await? .await?
@ -276,21 +340,25 @@ impl<'s> Element<'s> {
Node::Unknown => Err(JabberError::UnexpectedElement), Node::Unknown => Err(JabberError::UnexpectedElement),
} }
} }
pub async fn read_start<R: AsyncBufRead + Unpin + Send>(
pub async fn read_start<S: AsRef<str>, R: AsyncBufRead + Unpin + Send>(
reader: &mut Reader<R>, reader: &mut Reader<R>,
local_namespaces: &BTreeMap<Option<&str>, &str>, local_namespaces: &BTreeMap<Option<S>, S>,
) -> Result<Self> { ) -> Result<Element> {
let mut buf = Vec::new(); let buf = Vec::new();
let event = reader.read_event_into_async(&mut buf).await?; let event = reader.read_event_into_async(&mut buf).await?;
match event { match event {
Event::Start(e) => { Event::Start(e) => {
let prefix = e let prefix = e.name().prefix().map(|prefix| prefix.into_inner());
.name() let converted_prefix;
.prefix() if let Some(raw_prefix) = prefix {
.map(|prefix| str::from_utf8(prefix.into_inner())?); converted_prefix = Some(str::from_utf8(raw_prefix)?)
let localname = str::from_utf8(e.local_name().into_inner())?; }
let prefix = converted_prefix;
let mut namespaces = local_namespaces.clone(); let localname = str::from_utf8(e.local_name().into_inner())?.to_owned();
let mut local_namespaces = local_namespaces.clone();
let mut namespace_declarations = BTreeMap::new(); let mut namespace_declarations = BTreeMap::new();
let attributes = BTreeMap::new(); let attributes = BTreeMap::new();
@ -300,62 +368,70 @@ impl<'s> Element<'s> {
match prefix_declaration { match prefix_declaration {
PrefixDeclaration::Default => { PrefixDeclaration::Default => {
let value = str::from_utf8(attribute.value.as_ref())?; let value = str::from_utf8(attribute.value.as_ref())?;
namespace_declarations.try_insert(None, value); if let Some(_) = namespace_declarations.insert(None, value) {
namespaces.insert(None, value); return Err(ElementParseError::DuplicateAttribute.into());
};
local_namespaces.insert(None, value);
} }
PrefixDeclaration::Named(prefix) => { PrefixDeclaration::Named(prefix) => {
let key = str::from_utf8(prefix)?; let key = str::from_utf8(prefix)?;
let value = str::from_utf8(attribute.value.as_ref())?; let value = str::from_utf8(attribute.value.as_ref())?;
namespace_declarations if let Some(_) = namespace_declarations.insert(Some(key), value) {
.try_insert(Some(key), value) return Err(ElementParseError::DuplicateAttribute.into());
.map_err(ParseError::DuplicateAttribute)?; };
namespaces.insert(Some(key), value); local_namespaces.insert(Some(key), value);
} }
} }
} else { } else {
attributes if let Some(_) = attributes.insert(
.try_insert(
str::from_utf8(attribute.key.into_inner())?, str::from_utf8(attribute.key.into_inner())?,
str::from_utf8(attribute.value.as_ref())?, str::from_utf8(attribute.value.as_ref())?,
) ) {
.map_err(ParseError::DuplicateAttribute)?; return Err(ElementParseError::DuplicateAttribute.into());
};
} }
} }
let namespace = *namespaces.get(&prefix).ok_or(ParseError::NoNamespace)?; let namespace = *local_namespaces
.get(&prefix)
.ok_or(ElementParseError::NoNamespace)?;
let mut children = Vec::new(); let mut children = Vec::new();
Ok(Some(Self::Element(Element { Ok(Self {
prefix, prefix,
localname, localname,
namespace, namespace,
namespace_declarations, namespace_declarations: Box::new(namespace_declarations),
attributes, attributes: Box::new(attributes),
children, children: Box::new(children),
}))) })
} }
e => Err(ElementError::NotAStart(e)), e => Err(ElementError::NotAStart(e).into()),
} }
} }
} }
impl<'s> Node<'s> { impl Node {
async fn read_recursive<R: AsyncBufRead + Unpin + Send>( #[async_recursion]
async fn read_recursive<S: AsRef<str>, R: AsyncBufRead + Unpin + Send>(
reader: &mut Reader<R>, reader: &mut Reader<R>,
local_namespaces: &BTreeMap<Option<&str>, &str>, local_namespaces: &BTreeMap<Option<S>, S>,
) -> Result<Option<Node<'s>>> { ) -> Result<Option<Node>> {
let mut buf = Vec::new(); let mut buf = Vec::new();
let event = reader.read_event_into_async(&mut buf).await?; let event = reader.read_event_into_async(&mut buf).await?;
match event { match event {
Event::Empty(e) => { Event::Empty(e) => {
let prefix = e let prefix = e.name().prefix().map(|prefix| prefix.into_inner());
.name() let converted_prefix;
.prefix() if let Some(raw_prefix) = prefix {
.map(|prefix| str::from_utf8(prefix.into_inner())?); converted_prefix = Some(str::from_utf8(raw_prefix)?)
let localname = str::from_utf8(e.local_name().into_inner())?; }
let prefix = converted_prefix;
let mut namespaces = local_namespaces.clone(); let localname = str::from_utf8(e.local_name().into_inner())?.to_owned();
let mut local_namespaces = local_namespaces.clone();
let mut namespace_declarations = BTreeMap::new(); let mut namespace_declarations = BTreeMap::new();
let attributes = BTreeMap::new(); let attributes = BTreeMap::new();
@ -365,49 +441,56 @@ impl<'s> Node<'s> {
match prefix_declaration { match prefix_declaration {
PrefixDeclaration::Default => { PrefixDeclaration::Default => {
let value = str::from_utf8(attribute.value.as_ref())?; let value = str::from_utf8(attribute.value.as_ref())?;
namespace_declarations.try_insert(None, value); if let Some(_) = namespace_declarations.insert(None, value) {
namespaces.insert(None, value); return Err(ElementParseError::DuplicateAttribute.into());
};
local_namespaces.insert(None, value);
} }
PrefixDeclaration::Named(prefix) => { PrefixDeclaration::Named(prefix) => {
let key = str::from_utf8(prefix)?; let key = str::from_utf8(prefix)?;
let value = str::from_utf8(attribute.value.as_ref())?; let value = str::from_utf8(attribute.value.as_ref())?;
namespace_declarations if let Some(_) = namespace_declarations.insert(Some(key), value) {
.try_insert(Some(key), value) return Err(ElementParseError::DuplicateAttribute.into());
.map_err(ParseError::DuplicateAttribute)?; };
namespaces.insert(Some(key), value); local_namespaces.insert(Some(key), value);
} }
} }
} else { } else {
attributes if let Some(_) = attributes.insert(
.try_insert(
str::from_utf8(attribute.key.into_inner())?, str::from_utf8(attribute.key.into_inner())?,
str::from_utf8(attribute.value.as_ref())?, str::from_utf8(attribute.value.as_ref())?,
) ) {
.map_err(ParseError::DuplicateAttribute)?; return Err(ElementParseError::DuplicateAttribute.into());
};
} }
} }
let namespace = *namespaces.get(&prefix).ok_or(ParseError::NoNamespace)?; let namespace = *local_namespaces
.get(&prefix)
.ok_or(ElementParseError::NoNamespace)?;
let children = Vec::new(); let mut children = Vec::new();
Ok(Some(Self::Element(Element { Ok(Some(Self::Element(Element {
prefix, prefix,
localname, localname,
namespace, namespace,
namespace_declarations, namespace_declarations: Box::new(namespace_declarations),
attributes, attributes: Box::new(attributes),
children, children: Box::new(children),
}))) })))
} }
Event::Start(e) => { Event::Start(e) => {
let prefix = e let prefix = e.name().prefix().map(|prefix| prefix.into_inner());
.name() let converted_prefix;
.prefix() if let Some(raw_prefix) = prefix {
.map(|prefix| str::from_utf8(prefix.into_inner())?); converted_prefix = Some(str::from_utf8(raw_prefix)?)
let localname = str::from_utf8(e.local_name().into_inner())?; }
let prefix = converted_prefix;
let mut namespaces = local_namespaces.clone(); let localname = str::from_utf8(e.local_name().into_inner())?.to_owned();
let mut local_namespaces = local_namespaces.clone();
let mut namespace_declarations = BTreeMap::new(); let mut namespace_declarations = BTreeMap::new();
let attributes = BTreeMap::new(); let attributes = BTreeMap::new();
@ -417,92 +500,82 @@ impl<'s> Node<'s> {
match prefix_declaration { match prefix_declaration {
PrefixDeclaration::Default => { PrefixDeclaration::Default => {
let value = str::from_utf8(attribute.value.as_ref())?; let value = str::from_utf8(attribute.value.as_ref())?;
namespace_declarations.try_insert(None, value); if let Some(_) = namespace_declarations.insert(None, value) {
namespaces.insert(None, value); return Err(ElementParseError::DuplicateAttribute.into());
};
local_namespaces.insert(None, value);
} }
PrefixDeclaration::Named(prefix) => { PrefixDeclaration::Named(prefix) => {
let key = str::from_utf8(prefix)?; let key = str::from_utf8(prefix)?;
let value = str::from_utf8(attribute.value.as_ref())?; let value = str::from_utf8(attribute.value.as_ref())?;
namespace_declarations if let Some(_) = namespace_declarations.insert(Some(key), value) {
.try_insert(Some(key), value) return Err(ElementParseError::DuplicateAttribute.into());
.map_err(ParseError::DuplicateAttribute)?; };
namespaces.insert(Some(key), value); local_namespaces.insert(Some(key), value);
} }
} }
} else { } else {
attributes if let Some(_) = attributes.insert(
.try_insert(
str::from_utf8(attribute.key.into_inner())?, str::from_utf8(attribute.key.into_inner())?,
str::from_utf8(attribute.value.as_ref())?, str::from_utf8(attribute.value.as_ref())?,
) ) {
.map_err(ParseError::DuplicateAttribute)?; return Err(ElementParseError::DuplicateAttribute.into());
};
} }
} }
let namespace = *namespaces.get(&prefix).ok_or(ParseError::NoNamespace)?; let namespace = *local_namespaces
.get(&prefix)
.ok_or(ElementParseError::NoNamespace)?;
let mut children = Vec::new(); let mut children = Vec::new();
while let Some(child_node) = Node::read_recursive(reader, &namespaces).await? { while let Some(child_node) = Node::read_recursive(reader, &local_namespaces).await?
{
children.push(child_node) children.push(child_node)
} }
let mut children = Vec::new();
Ok(Some(Self::Element(Element { Ok(Some(Self::Element(Element {
prefix, prefix,
localname, localname,
namespace, namespace,
namespace_declarations, namespace_declarations: Box::new(namespace_declarations),
attributes, attributes: Box::new(attributes),
children, children: Box::new(children),
}))) })))
} }
Event::End(_) => Ok(None), Event::End(_) => Ok(None),
Event::Text(e) => Ok(Some(Self::Text(e.unescape()?.as_ref()))), Event::Text(e) => Ok(Some(Self::Text(e.unescape()?.as_ref().to_string()))),
e => Ok(Some(Self::Unknown)), e => Ok(Some(Self::Unknown)),
} }
} }
fn namespace_qualified<S: AsRef<str>>(
&self,
local_namespaces: &BTreeMap<Option<S>, S>,
) -> bool {
match self {
Self::Element(e) => e.namespace_qualified(local_namespaces),
_ => true,
}
}
} }
// #[async_recursion] // the issue is i don't know how to validate that an element always has a namespace when it is being written
// pub async fn read_start<R: AsyncBufRead + Unpin + Send>( // TODO: ElementBuilder that makes it easier to build an element under a namespace
// reader: &mut Reader<R>,
// ) -> Result<Self, JabberError> {
// let mut buf = Vec::new();
// let event = reader.read_event_into_async(&mut buf).await?;
// match event {
// Event::Start(e) => {
// return Ok(Self {
// event: Event::Start(e.into_owned()),
// children: None,
// })
// }
// e => Err(ElementError::NotAStart(e.into_owned()).into()),
// }
// }
// pub trait IntoElement<'e> {
// fn event(&self) -> Event<'e>;
// fn children(&self) -> Option<Vec<Element<'e>>>;
// }
// impl<'e, T: IntoElement<'e>> From<T> for Element<'e> {
// fn from(value: T) -> Self {
// Element {
// event: value.event(),
// children: value.children(),
// }
// }
// }
#[derive(Debug)] #[derive(Debug)]
pub enum ElementError<'e> { pub enum ElementError<'e> {
NotAStart(Event<'e>), NotAStart(Event<'e>),
NotText, NotText,
NoChildren, NoChildren,
NamespaceNotQualified,
MultipleChildren, MultipleChildren,
} }
#[derive(Debug)] #[derive(Debug)]
pub enum ParseError { pub enum ElementParseError {
DuplicateAttribute, DuplicateAttribute,
NoNamespace, NoNamespace,
} }