2023-07-11 21:28:42 +01:00
// use quick_xml::events::BytesDecl;
2023-08-02 00:56:38 +01:00
pub mod bind ;
pub mod iq ;
2023-07-04 21:27:15 +01:00
pub mod sasl ;
2023-06-19 19:23:54 +01:00
pub mod stream ;
2023-07-11 21:28:42 +01:00
2023-08-02 18:21:57 +01:00
use std ::collections ::BTreeMap ;
2023-08-05 16:47:52 +01:00
use std ::str ;
2023-08-02 18:21:57 +01:00
2023-07-11 21:28:42 +01:00
// const DECLARATION: BytesDecl<'_> = BytesDecl::new("1.0", None, None);
2023-07-12 12:41:36 +01:00
use async_recursion ::async_recursion ;
2023-08-05 16:47:52 +01:00
use quick_xml ::events ::{ BytesEnd , BytesStart , BytesText , Event } ;
2023-08-05 17:38:50 +01:00
use quick_xml ::name ::PrefixDeclaration ;
2023-07-12 12:41:36 +01:00
use quick_xml ::{ Reader , Writer } ;
use tokio ::io ::{ AsyncBufRead , AsyncWrite } ;
2023-08-05 16:47:52 +01:00
use crate ::{ JabberError , Result } ;
2023-07-12 12:41:36 +01:00
2023-08-02 18:21:57 +01:00
pub type Prefix < ' s > = Option < & ' s str > ;
#[ derive(Clone, Debug) ]
/// represents an xml element as a tree of nodes
2023-08-05 20:14:09 +01:00
pub struct Element {
2023-08-02 18:21:57 +01:00
/// element prefix
/// e.g. `foo` in `<foo:bar />`.
2023-08-05 20:14:09 +01:00
prefix : Option < String > ,
2023-08-05 16:47:52 +01:00
/// element name
/// e.g. `bar` in `<foo:bar />`.
2023-08-05 20:14:09 +01:00
localname : String ,
2023-08-02 18:21:57 +01:00
/// qualifying namespace
/// an element must be qualified by a namespace
/// e.g. for `<stream:features>` in
/// ```
/// <stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'>
/// <stream:features>
/// <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>
/// <compression xmlns='http://jabber.org/features/compress'>
/// <method>zlib</method>
/// <method>lzw</method>
/// </compression>
/// </stream:features>
/// </stream:stream>
/// ```
/// would be `"http://etherx.jabber.org/streams"` but for
/// ```
/// <stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'>
/// <features>
/// <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>
/// <compression xmlns='http://jabber.org/features/compress'>
/// <method>zlib</method>
/// <method>lzw</method>
/// </compression>
/// </features>
/// </stream:stream>
/// ```
/// would be `"jabber:client"`
2023-08-05 20:14:09 +01:00
namespace : String ,
2023-08-02 18:21:57 +01:00
/// all namespaces applied to element
/// e.g. for `<bind>` in
/// ```
/// <stream:features xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'>
/// <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>
/// <compression xmlns='http://jabber.org/features/compress'>
/// <method>zlib</method>
/// <method>lzw</method>
/// </compression>
/// </stream:features>
/// ```
/// would be `[(None, "urn:ietf:params:xml:ns:xmpp-bind")]` despite
/// `(Some("stream"), "http://etherx.jabber.org/streams")` also being available
2023-08-05 20:14:09 +01:00
// 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 > > ,
2023-08-02 18:21:57 +01:00
/// element attributes
2023-08-05 20:14:09 +01:00
attributes : Box < BTreeMap < String , String > > ,
2023-08-02 18:21:57 +01:00
// children elements namespaces contain their parents' namespaces
2023-08-05 20:14:09 +01:00
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 ) { }
2023-08-02 18:21:57 +01:00
}
2023-07-12 21:11:20 +01:00
#[ derive(Clone, Debug) ]
2023-08-05 20:14:09 +01:00
pub enum Node {
Element ( Element ) ,
Text ( String ) ,
2023-08-05 17:38:50 +01:00
Unknown ,
2023-08-02 18:21:57 +01:00
}
2023-08-05 20:14:09 +01:00
impl From < Element > for Node {
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 {
2023-08-05 16:47:52 +01:00
match node {
Node ::Element ( e ) = > e . into ( ) ,
Node ::Text ( t ) = > vec! [ Event ::Text ( BytesText ::new ( t ) ) ] ,
2023-08-05 17:38:50 +01:00
Unknown = > vec! [ ] ,
2023-08-05 16:47:52 +01:00
}
}
}
2023-08-05 20:14:09 +01:00
impl Element {
2023-08-05 16:47:52 +01:00
/// returns the fully qualified name
/// e.g. `foo:bar` in
/// `<foo:bar>`.
pub fn name ( & self ) -> & str {
if let Some ( prefix ) = self . prefix {
format! ( " {} : {} " , prefix , self . localname ) . as_str ( )
2023-08-02 18:21:57 +01:00
} else {
2023-08-05 20:14:09 +01:00
& self . localname
2023-08-02 18:21:57 +01:00
}
2023-08-05 16:47:52 +01:00
}
2023-08-02 18:21:57 +01:00
2023-08-05 16:47:52 +01:00
/// returns the localname.
/// e.g. `bar` in `<foo:bar>`
pub fn localname ( & self ) -> & str {
2023-08-05 20:14:09 +01:00
& self . localname
2023-08-05 16:47:52 +01:00
}
2023-08-02 18:21:57 +01:00
2023-08-05 16:47:52 +01:00
/// returns the prefix.
/// e.g. `foo` in `<foo:bar>`. returns None if there is
/// no prefix.
pub fn prefix ( & self ) -> Option < & str > {
self . prefix
2023-08-02 18:21:57 +01:00
}
/// returns the namespace which applies to the current element, e.g. for
2023-08-05 16:47:52 +01:00
/// `<element xmlns='foo' xmlns:bar='bar'>`
/// it will be `foo` but for
/// `<bar:element xmlns='foo' xmlns:bar='bar'>`
/// it will be `bar`.
pub fn namespace ( & self ) -> & str {
2023-08-05 20:14:09 +01:00
& self . namespace
2023-08-02 18:21:57 +01:00
}
2023-07-12 12:41:36 +01:00
}
2023-08-05 20:14:09 +01:00
impl < ' s > From < & Element > for Vec < Event < ' s > > {
fn from ( element : & Element ) -> Self {
2023-08-05 16:47:52 +01:00
let name = element . name ( ) ;
let event = BytesStart ::new ( name ) ;
// namespace declarations
let namespace_declarations = element . namespace_declarations . iter ( ) . map ( | declaration | {
let ( prefix , namespace ) = declaration ;
match prefix {
Some ( prefix ) = > return ( format! ( " xmlns: {} " , prefix ) . as_str ( ) , * namespace ) ,
None = > return ( " xmlns " , * namespace ) ,
2023-08-02 18:21:57 +01:00
}
2023-08-05 16:47:52 +01:00
} ) ;
let event = event . with_attributes ( namespace_declarations ) ;
// attributes
let event = event . with_attributes ( element . attributes . into_iter ( ) ) ;
match element . children . is_empty ( ) {
true = > return vec! [ Event ::Empty ( event ) ] ,
false = > {
return {
let start : Vec < Event < ' s > > = vec! [ Event ::Start ( event ) ] ;
let start_and_content : Vec < Event < ' s > > = start
. into_iter ( )
. chain ( {
let u = element . children . iter ( ) . fold (
Vec ::new ( ) ,
| acc : Vec < Event < ' s > > , child : & Node < ' s > | {
acc . into_iter ( )
. chain ( Into ::< Vec < Event < ' s > > > ::into ( child ) . into_iter ( ) )
. collect ( )
} ,
) ;
u
} )
. collect ( ) ;
let full : Vec < Event < ' s > > = start_and_content
. into_iter ( )
. chain ( vec! [ Event ::End ( BytesEnd ::new ( name ) ) ] )
. collect ( ) ;
full
2023-07-12 12:41:36 +01:00
}
}
2023-08-05 16:47:52 +01:00
}
2023-07-12 12:41:36 +01:00
}
}
2023-08-05 20:14:09 +01:00
impl Element {
2023-08-05 16:47:52 +01:00
/// if there is only one child in the vec of children, will return that element
2023-08-05 20:14:09 +01:00
pub fn child ( & self ) -> Result < & Node > {
2023-08-05 16:47:52 +01:00
if self . children . len ( ) = = 1 {
Ok ( & self . children [ 0 ] )
2023-08-05 17:38:50 +01:00
} else if self . children . len ( ) > 1 {
Err ( ElementError ::MultipleChildren . into ( ) )
2023-08-05 16:47:52 +01:00
} else {
Err ( ElementError ::NoChildren . into ( ) )
}
}
/// returns reference to children
2023-08-05 20:14:09 +01:00
pub fn children ( & self ) -> Result < & Vec < Node > > {
2023-08-05 16:47:52 +01:00
if ! self . children . is_empty ( ) {
Ok ( & self . children )
} else {
Err ( ElementError ::NoChildren . into ( ) )
}
}
/// returns text content, error if there is none
2023-08-05 17:38:50 +01:00
pub fn text_content ( & self ) -> Result < Vec < & str > > {
2023-08-05 20:14:09 +01:00
let mut text = Vec ::new ( ) ;
2023-08-05 16:47:52 +01:00
for node in * self . children {
match node {
2023-08-05 17:38:50 +01:00
Node ::Text ( t ) = > text . push ( t ) ,
2023-08-05 16:47:52 +01:00
_ = > { }
}
}
2023-08-05 17:38:50 +01:00
if text . is_empty ( ) {
2023-08-05 20:14:09 +01:00
return Err ( ElementError ::NotText . into ( ) ) ;
2023-08-05 17:38:50 +01:00
}
Ok ( text )
2023-08-05 16:47:52 +01:00
}
2023-08-05 20:14:09 +01:00
/// 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 ;
}
2023-08-05 16:47:52 +01:00
}
2023-08-05 20:14:09 +01:00
true
2023-08-05 16:47:52 +01:00
}
2023-08-05 20:14:09 +01:00
/// 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 > (
2023-07-12 12:41:36 +01:00
& self ,
writer : & mut Writer < W > ,
2023-08-05 20:14:09 +01:00
local_namespaces : & BTreeMap < Option < S > , S > ,
2023-08-05 16:47:52 +01:00
) -> Result < ( ) > {
2023-08-05 20:14:09 +01:00
// 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 ( ) ;
for event in events {
writer . write_event_async ( event ) . await ?
}
Ok ( ( ) )
} else {
Err ( ElementError ::NamespaceNotQualified . into ( ) )
}
}
2023-08-05 16:47:52 +01:00
2023-08-05 20:14:09 +01:00
pub async fn write_start < S : AsRef < str > , W : AsyncWrite + Unpin + Send > (
& self ,
writer : & mut Writer < W > ,
local_namespaces : & BTreeMap < Option < S > , S > ,
) -> Result < ( ) > {
if self . namespace_qualified ( local_namespaces ) {
let mut event = BytesStart ::new ( self . name ( ) ) ;
// namespace declarations
self . namespace_declarations . iter ( ) . for_each ( | declaration | {
let ( prefix , namespace ) = declaration ;
match prefix {
Some ( prefix ) = > {
event . push_attribute ( ( format! ( " xmlns: {} " , prefix ) . as_str ( ) , * namespace ) )
}
None = > event . push_attribute ( ( " xmlns " , * namespace ) ) ,
2023-08-05 16:47:52 +01:00
}
2023-08-05 20:14:09 +01:00
} ) ;
2023-08-05 16:47:52 +01:00
2023-08-05 20:14:09 +01:00
// attributes
let event =
event . with_attributes ( self . attributes . iter ( ) . map ( | ( attr , value ) | ( * attr , * value ) ) ) ;
2023-08-05 16:47:52 +01:00
2023-08-05 20:14:09 +01:00
writer . write_event_async ( Event ::Start ( event ) ) . await ? ;
2023-08-05 16:47:52 +01:00
2023-08-05 20:14:09 +01:00
Ok ( ( ) )
} else {
Err ( ElementError ::NamespaceNotQualified . into ( ) )
}
2023-07-12 12:41:36 +01:00
}
pub async fn write_end < W : AsyncWrite + Unpin + Send > (
& self ,
writer : & mut Writer < W > ,
2023-08-05 16:47:52 +01:00
) -> Result < ( ) > {
let event = BytesEnd ::new ( self . name ( ) ) ;
writer . write_event_async ( Event ::End ( event ) ) . await ? ;
Ok ( ( ) )
2023-07-12 12:41:36 +01:00
}
#[ async_recursion ]
2023-08-05 20:14:09 +01:00
pub async fn read < S : AsRef < str > , R : AsyncBufRead + Unpin + Send > (
2023-07-12 12:41:36 +01:00
reader : & mut Reader < R > ,
2023-08-05 20:14:09 +01:00
local_namespaces : & BTreeMap < Option < S > , S > ,
2023-08-05 16:47:52 +01:00
) -> Result < Self > {
let node = Node ::read_recursive ( reader , local_namespaces )
2023-07-12 21:11:20 +01:00
. await ?
2023-08-05 16:47:52 +01:00
. ok_or ( JabberError ::UnexpectedEnd ) ? ;
match node {
Node ::Element ( e ) = > Ok ( e ) ,
Node ::Text ( _ ) = > Err ( JabberError ::UnexpectedText ) ,
2023-08-05 17:38:50 +01:00
Node ::Unknown = > Err ( JabberError ::UnexpectedElement ) ,
}
}
2023-08-05 20:14:09 +01:00
pub async fn read_start < S : AsRef < str > , R : AsyncBufRead + Unpin + Send > (
2023-08-05 17:38:50 +01:00
reader : & mut Reader < R > ,
2023-08-05 20:14:09 +01:00
local_namespaces : & BTreeMap < Option < S > , S > ,
) -> Result < Element > {
let buf = Vec ::new ( ) ;
2023-08-05 17:38:50 +01:00
let event = reader . read_event_into_async ( & mut buf ) . await ? ;
match event {
Event ::Start ( e ) = > {
2023-08-05 20:14:09 +01:00
let prefix = e . name ( ) . prefix ( ) . map ( | prefix | prefix . into_inner ( ) ) ;
let converted_prefix ;
if let Some ( raw_prefix ) = prefix {
converted_prefix = Some ( str ::from_utf8 ( raw_prefix ) ? )
}
let prefix = converted_prefix ;
let localname = str ::from_utf8 ( e . local_name ( ) . into_inner ( ) ) ? . to_owned ( ) ;
2023-08-05 17:38:50 +01:00
2023-08-05 20:14:09 +01:00
let mut local_namespaces = local_namespaces . clone ( ) ;
2023-08-05 17:38:50 +01:00
let mut namespace_declarations = BTreeMap ::new ( ) ;
let attributes = BTreeMap ::new ( ) ;
for attribute in e . attributes ( ) {
let attribute = attribute ? ;
if let Some ( prefix_declaration ) = attribute . key . as_namespace_binding ( ) {
match prefix_declaration {
PrefixDeclaration ::Default = > {
let value = str ::from_utf8 ( attribute . value . as_ref ( ) ) ? ;
2023-08-05 20:14:09 +01:00
if let Some ( _ ) = namespace_declarations . insert ( None , value ) {
return Err ( ElementParseError ::DuplicateAttribute . into ( ) ) ;
} ;
local_namespaces . insert ( None , value ) ;
2023-08-05 17:38:50 +01:00
}
PrefixDeclaration ::Named ( prefix ) = > {
let key = str ::from_utf8 ( prefix ) ? ;
let value = str ::from_utf8 ( attribute . value . as_ref ( ) ) ? ;
2023-08-05 20:14:09 +01:00
if let Some ( _ ) = namespace_declarations . insert ( Some ( key ) , value ) {
return Err ( ElementParseError ::DuplicateAttribute . into ( ) ) ;
} ;
local_namespaces . insert ( Some ( key ) , value ) ;
2023-08-05 17:38:50 +01:00
}
}
} else {
2023-08-05 20:14:09 +01:00
if let Some ( _ ) = attributes . insert (
str ::from_utf8 ( attribute . key . into_inner ( ) ) ? ,
str ::from_utf8 ( attribute . value . as_ref ( ) ) ? ,
) {
return Err ( ElementParseError ::DuplicateAttribute . into ( ) ) ;
} ;
2023-08-05 17:38:50 +01:00
}
}
2023-08-05 20:14:09 +01:00
let namespace = * local_namespaces
. get ( & prefix )
. ok_or ( ElementParseError ::NoNamespace ) ? ;
2023-08-05 17:38:50 +01:00
let mut children = Vec ::new ( ) ;
2023-08-05 20:14:09 +01:00
Ok ( Self {
2023-08-05 17:38:50 +01:00
prefix ,
localname ,
namespace ,
2023-08-05 20:14:09 +01:00
namespace_declarations : Box ::new ( namespace_declarations ) ,
attributes : Box ::new ( attributes ) ,
children : Box ::new ( children ) ,
} )
2023-08-05 17:38:50 +01:00
}
2023-08-05 20:14:09 +01:00
e = > Err ( ElementError ::NotAStart ( e ) . into ( ) ) ,
2023-08-05 16:47:52 +01:00
}
2023-07-12 21:11:20 +01:00
}
2023-08-05 16:47:52 +01:00
}
2023-07-12 21:11:20 +01:00
2023-08-05 20:14:09 +01:00
impl Node {
#[ async_recursion ]
async fn read_recursive < S : AsRef < str > , R : AsyncBufRead + Unpin + Send > (
2023-07-12 21:11:20 +01:00
reader : & mut Reader < R > ,
2023-08-05 20:14:09 +01:00
local_namespaces : & BTreeMap < Option < S > , S > ,
) -> Result < Option < Node > > {
2023-07-12 12:41:36 +01:00
let mut buf = Vec ::new ( ) ;
let event = reader . read_event_into_async ( & mut buf ) . await ? ;
match event {
2023-08-05 17:38:50 +01:00
Event ::Empty ( e ) = > {
2023-08-05 20:14:09 +01:00
let prefix = e . name ( ) . prefix ( ) . map ( | prefix | prefix . into_inner ( ) ) ;
let converted_prefix ;
if let Some ( raw_prefix ) = prefix {
converted_prefix = Some ( str ::from_utf8 ( raw_prefix ) ? )
}
let prefix = converted_prefix ;
let localname = str ::from_utf8 ( e . local_name ( ) . into_inner ( ) ) ? . to_owned ( ) ;
2023-08-05 17:38:50 +01:00
2023-08-05 20:14:09 +01:00
let mut local_namespaces = local_namespaces . clone ( ) ;
2023-08-05 17:38:50 +01:00
let mut namespace_declarations = BTreeMap ::new ( ) ;
let attributes = BTreeMap ::new ( ) ;
for attribute in e . attributes ( ) {
let attribute = attribute ? ;
if let Some ( prefix_declaration ) = attribute . key . as_namespace_binding ( ) {
match prefix_declaration {
PrefixDeclaration ::Default = > {
let value = str ::from_utf8 ( attribute . value . as_ref ( ) ) ? ;
2023-08-05 20:14:09 +01:00
if let Some ( _ ) = namespace_declarations . insert ( None , value ) {
return Err ( ElementParseError ::DuplicateAttribute . into ( ) ) ;
} ;
local_namespaces . insert ( None , value ) ;
2023-08-05 17:38:50 +01:00
}
PrefixDeclaration ::Named ( prefix ) = > {
let key = str ::from_utf8 ( prefix ) ? ;
let value = str ::from_utf8 ( attribute . value . as_ref ( ) ) ? ;
2023-08-05 20:14:09 +01:00
if let Some ( _ ) = namespace_declarations . insert ( Some ( key ) , value ) {
return Err ( ElementParseError ::DuplicateAttribute . into ( ) ) ;
} ;
local_namespaces . insert ( Some ( key ) , value ) ;
2023-08-05 17:38:50 +01:00
}
}
} else {
2023-08-05 20:14:09 +01:00
if let Some ( _ ) = attributes . insert (
str ::from_utf8 ( attribute . key . into_inner ( ) ) ? ,
str ::from_utf8 ( attribute . value . as_ref ( ) ) ? ,
) {
return Err ( ElementParseError ::DuplicateAttribute . into ( ) ) ;
} ;
2023-08-05 17:38:50 +01:00
}
}
2023-08-05 20:14:09 +01:00
let namespace = * local_namespaces
. get ( & prefix )
. ok_or ( ElementParseError ::NoNamespace ) ? ;
2023-08-05 17:38:50 +01:00
2023-08-05 20:14:09 +01:00
let mut children = Vec ::new ( ) ;
2023-08-05 17:38:50 +01:00
Ok ( Some ( Self ::Element ( Element {
prefix ,
localname ,
namespace ,
2023-08-05 20:14:09 +01:00
namespace_declarations : Box ::new ( namespace_declarations ) ,
attributes : Box ::new ( attributes ) ,
children : Box ::new ( children ) ,
2023-08-05 17:38:50 +01:00
} ) ) )
}
2023-07-12 12:41:36 +01:00
Event ::Start ( e ) = > {
2023-08-05 20:14:09 +01:00
let prefix = e . name ( ) . prefix ( ) . map ( | prefix | prefix . into_inner ( ) ) ;
let converted_prefix ;
if let Some ( raw_prefix ) = prefix {
converted_prefix = Some ( str ::from_utf8 ( raw_prefix ) ? )
}
let prefix = converted_prefix ;
let localname = str ::from_utf8 ( e . local_name ( ) . into_inner ( ) ) ? . to_owned ( ) ;
2023-08-05 17:38:50 +01:00
2023-08-05 20:14:09 +01:00
let mut local_namespaces = local_namespaces . clone ( ) ;
2023-08-05 17:38:50 +01:00
let mut namespace_declarations = BTreeMap ::new ( ) ;
let attributes = BTreeMap ::new ( ) ;
for attribute in e . attributes ( ) {
let attribute = attribute ? ;
if let Some ( prefix_declaration ) = attribute . key . as_namespace_binding ( ) {
match prefix_declaration {
PrefixDeclaration ::Default = > {
let value = str ::from_utf8 ( attribute . value . as_ref ( ) ) ? ;
2023-08-05 20:14:09 +01:00
if let Some ( _ ) = namespace_declarations . insert ( None , value ) {
return Err ( ElementParseError ::DuplicateAttribute . into ( ) ) ;
} ;
local_namespaces . insert ( None , value ) ;
2023-08-05 17:38:50 +01:00
}
PrefixDeclaration ::Named ( prefix ) = > {
let key = str ::from_utf8 ( prefix ) ? ;
let value = str ::from_utf8 ( attribute . value . as_ref ( ) ) ? ;
2023-08-05 20:14:09 +01:00
if let Some ( _ ) = namespace_declarations . insert ( Some ( key ) , value ) {
return Err ( ElementParseError ::DuplicateAttribute . into ( ) ) ;
} ;
local_namespaces . insert ( Some ( key ) , value ) ;
2023-08-05 17:38:50 +01:00
}
}
} else {
2023-08-05 20:14:09 +01:00
if let Some ( _ ) = attributes . insert (
str ::from_utf8 ( attribute . key . into_inner ( ) ) ? ,
str ::from_utf8 ( attribute . value . as_ref ( ) ) ? ,
) {
return Err ( ElementParseError ::DuplicateAttribute . into ( ) ) ;
} ;
2023-08-05 17:38:50 +01:00
}
}
2023-08-05 16:47:52 +01:00
2023-08-05 20:14:09 +01:00
let namespace = * local_namespaces
. get ( & prefix )
. ok_or ( ElementParseError ::NoNamespace ) ? ;
2023-08-05 17:38:50 +01:00
let mut children = Vec ::new ( ) ;
2023-08-05 20:14:09 +01:00
while let Some ( child_node ) = Node ::read_recursive ( reader , & local_namespaces ) . await ?
{
2023-08-05 17:38:50 +01:00
children . push ( child_node )
2023-07-12 12:41:36 +01:00
}
2023-08-05 17:38:50 +01:00
2023-08-05 20:14:09 +01:00
let mut children = Vec ::new ( ) ;
2023-08-05 16:47:52 +01:00
Ok ( Some ( Self ::Element ( Element {
prefix ,
2023-08-05 17:38:50 +01:00
localname ,
namespace ,
2023-08-05 20:14:09 +01:00
namespace_declarations : Box ::new ( namespace_declarations ) ,
attributes : Box ::new ( attributes ) ,
children : Box ::new ( children ) ,
2023-08-05 16:47:52 +01:00
} ) ) )
2023-07-12 12:41:36 +01:00
}
Event ::End ( _ ) = > Ok ( None ) ,
2023-08-05 20:14:09 +01:00
Event ::Text ( e ) = > Ok ( Some ( Self ::Text ( e . unescape ( ) ? . as_ref ( ) . to_string ( ) ) ) ) ,
2023-08-05 17:38:50 +01:00
e = > Ok ( Some ( Self ::Unknown ) ) ,
2023-07-12 12:41:36 +01:00
}
}
2023-08-05 20:14:09 +01:00
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 ,
}
}
2023-07-12 21:11:20 +01:00
}
2023-08-05 20:14:09 +01:00
// the issue is i don't know how to validate that an element always has a namespace when it is being written
// TODO: ElementBuilder that makes it easier to build an element under a namespace
2023-07-12 21:11:20 +01:00
2023-07-12 12:41:36 +01:00
#[ derive(Debug) ]
pub enum ElementError < ' e > {
NotAStart ( Event < ' e > ) ,
2023-08-05 16:47:52 +01:00
NotText ,
2023-07-12 21:11:20 +01:00
NoChildren ,
2023-08-05 20:14:09 +01:00
NamespaceNotQualified ,
2023-07-12 21:11:20 +01:00
MultipleChildren ,
2023-07-12 12:41:36 +01:00
}
2023-08-05 17:38:50 +01:00
#[ derive(Debug) ]
2023-08-05 20:14:09 +01:00
pub enum ElementParseError {
2023-08-05 17:38:50 +01:00
DuplicateAttribute ,
NoNamespace ,
}