diff options
Diffstat (limited to '')
| -rw-r--r-- | src/element.rs | 6 | ||||
| -rw-r--r-- | src/error.rs | 1 | ||||
| -rw-r--r-- | src/lib.rs | 2 | ||||
| -rw-r--r-- | src/reader.rs | 117 | 
4 files changed, 122 insertions, 4 deletions
| diff --git a/src/element.rs b/src/element.rs index 0e0b8f1..e93a0f3 100644 --- a/src/element.rs +++ b/src/element.rs @@ -9,19 +9,20 @@ 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)] +#[derive(PartialEq, Eq, Hash, Clone, Debug)]  pub struct Namespace {      pub prefix: Option<String>,      pub namespace: String,  }  // names are qualified, they contain a reference to the namespace (held within the reader/writer) -#[derive(PartialEq, Eq, Hash, Clone)] +#[derive(PartialEq, Eq, Hash, Clone, Debug)]  pub struct Name {      pub namespace: Namespace,      pub name: String,  } +#[derive(Debug)]  pub enum Content {      Element(Element),      Text(String), @@ -30,6 +31,7 @@ pub enum Content {  }  // should this be a trait? +#[derive(Debug)]  pub struct Element {      pub name: Name,      // namespace: Name, diff --git a/src/error.rs b/src/error.rs index 96c709c..1f9c1e6 100644 --- a/src/error.rs +++ b/src/error.rs @@ -2,6 +2,7 @@ use std::{num::ParseIntError, str::Utf8Error};  use crate::element::{Name, Namespace}; +#[derive(Debug)]  pub enum Error {      ReadError(std::io::Error),      Utf8Error(Utf8Error), @@ -1,6 +1,6 @@  mod element;  mod error; -mod reader; +pub mod reader;  mod writer;  pub mod xml; diff --git a/src/reader.rs b/src/reader.rs index b51489f..bca8edd 100644 --- a/src/reader.rs +++ b/src/reader.rs @@ -339,7 +339,7 @@ impl<R> Reader<R> {              }          }          text.map(|text| content.push(Content::Text(text))); -        todo!() +        Ok(content)      }  } @@ -422,3 +422,118 @@ impl<R> Reader<R> {  //         todo!()  //     }  // } + +#[cfg(test)] +mod test { +    use tokio::io::AsyncRead; + +    use super::Reader; + +    struct MockAsyncReader<'s>(&'s str); + +    impl<'s> MockAsyncReader<'s> { +        fn new(data: &'s str) -> Self { +            Self(data) +        } +    } + +    impl<'s> AsyncRead for MockAsyncReader<'s> { +        fn poll_read( +            self: std::pin::Pin<&mut Self>, +            _cx: &mut std::task::Context<'_>, +            buf: &mut tokio::io::ReadBuf<'_>, +        ) -> std::task::Poll<std::io::Result<()>> { +            buf.put_slice(self.0.as_bytes()); +            std::task::Poll::Ready(Ok(())) +        } +    } + +    #[tokio::test] +    async fn test_element_read() { +        let mock = MockAsyncReader::new( +            "<xs:schema +       xmlns:xs='http://www.w3.org/2001/XMLSchema' +       targetNamespace='http://etherx.jabber.org/streams' +       xmlns='http://etherx.jabber.org/streams' +       elementFormDefault='unqualified'> + +     <xs:import namespace='jabber:client'/> +     <xs:import namespace='jabber:server'/> +     <xs:import namespace='urn:ietf:params:xml:ns:xmpp-sasl'/> +     <xs:import namespace='urn:ietf:params:xml:ns:xmpp-streams'/> +     <xs:import namespace='urn:ietf:params:xml:ns:xmpp-tls'/> + +     <xs:element name='stream'> +       <xs:complexType> +         <xs:sequence xmlns:client='jabber:client' +                      xmlns:server='jabber:server'> +           <xs:element ref='features' +                       minOccurs='0' +                       maxOccurs='1'/> +           <xs:any namespace='urn:ietf:params:xml:ns:xmpp-tls' +                   minOccurs='0' +                   maxOccurs='1'/> +           <xs:any namespace='urn:ietf:params:xml:ns:xmpp-sasl' +                   minOccurs='0' +                   maxOccurs='1'/> +           <xs:any namespace='##other' +                   minOccurs='0' +                   maxOccurs='unbounded' +                   processContents='lax'/> +           <xs:choice minOccurs='0' maxOccurs='1'> +             <xs:choice minOccurs='0' maxOccurs='unbounded'> +               <xs:element ref='client:message'/> +               <xs:element ref='client:presence'/> +               <xs:element ref='client:iq'/> +             </xs:choice> +             <xs:choice minOccurs='0' maxOccurs='unbounded'> +               <xs:element ref='server:message'/> +               <xs:element ref='server:presence'/> +               <xs:element ref='server:iq'/> +             </xs:choice> +           </xs:choice> +           <xs:element ref='error' minOccurs='0' maxOccurs='1'/> +         </xs:sequence> +         <xs:attribute name='from' type='xs:string' use='optional'/> +         <xs:attribute name='id' type='xs:string' use='optional'/> +         <xs:attribute name='to' type='xs:string' use='optional'/> +         <xs:attribute name='version' type='xs:decimal' use='optional'/> +         <xs:attribute ref='xml:lang' use='optional'/> +         <xs:anyAttribute namespace='##other' processContents='lax'/> +       </xs:complexType> +     </xs:element> + +     <xs:element name='features'> +       <xs:complexType> +         <xs:sequence> +           <xs:any namespace='##other' +                   minOccurs='0' +                   maxOccurs='unbounded' +                   processContents='lax'/> +         </xs:sequence> +       </xs:complexType> +     </xs:element> + +     <xs:element name='error'> +       <xs:complexType> +         <xs:sequence  xmlns:err='urn:ietf:params:xml:ns:xmpp-streams'> +           <xs:group   ref='err:streamErrorGroup'/> +           <xs:element ref='err:text' +                       minOccurs='0' +                       maxOccurs='1'/> +           <xs:any     namespace='##other' +                       minOccurs='0' +                       maxOccurs='1' +                       processContents='lax'/> +         </xs:sequence> +       </xs:complexType> +     </xs:element> + +   </xs:schema>asdf +", +        ); +        let mut reader = Reader::new(mock); +        let element = reader.read_element().await.unwrap(); +        println!("{:#?}", element); +    } +} | 
