aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar cel 🌸 <cel@bunny.garden>2024-11-10 17:57:05 +0000
committerLibravatar cel 🌸 <cel@bunny.garden>2024-11-10 17:57:05 +0000
commit140af50536ebc32ae6461852daa2df0fc2d197ca (patch)
treee9d75cf617ed098fb3953407f806f5e38235b299
parentbe50ab4890993ae97bc79138364cd5e316566e46 (diff)
downloadpeanuts-140af50536ebc32ae6461852daa2df0fc2d197ca.tar.gz
peanuts-140af50536ebc32ae6461852daa2df0fc2d197ca.tar.bz2
peanuts-140af50536ebc32ae6461852daa2df0fc2d197ca.zip
implement reader testing
-rw-r--r--src/element.rs6
-rw-r--r--src/error.rs1
-rw-r--r--src/lib.rs2
-rw-r--r--src/reader.rs117
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),
diff --git a/src/lib.rs b/src/lib.rs
index 329c092..e8486c4 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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);
+ }
+}