aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar cel 🌸 <cel@bunny.garden>2025-05-29 20:44:03 +0100
committerLibravatar cel 🌸 <cel@bunny.garden>2025-05-29 20:44:03 +0100
commit5865d4c22ea86dda917dd2d502dc3399c9f7a261 (patch)
tree1e3c17b0afae6c1d26cf9f3bda0d7e05adab22d7 /src
parent94afe363ea88a6fd036d1681542d650e7cd3c2e7 (diff)
downloadpeanuts-5865d4c22ea86dda917dd2d502dc3399c9f7a261.tar.gz
peanuts-5865d4c22ea86dda917dd2d502dc3399c9f7a261.tar.bz2
peanuts-5865d4c22ea86dda917dd2d502dc3399c9f7a261.zip
doc: `Reader`
Diffstat (limited to 'src')
-rw-r--r--src/reader.rs32
1 files changed, 25 insertions, 7 deletions
diff --git a/src/reader.rs b/src/reader.rs
index a46c66b..ea6c804 100644
--- a/src/reader.rs
+++ b/src/reader.rs
@@ -29,11 +29,11 @@ use crate::{
static MAX_STANZA_SIZE: usize = 65536;
-/// streaming reader that tracks depth and available namespaces at current depth
+/// Streaming reader that tracks depth and corresponding available namespaces.
#[derive(Debug)]
pub struct Reader<R> {
inner: R,
- pub buffer: Buffer,
+ buffer: Buffer,
// holds which tags we are in atm over depth
// to have names reference namespaces could
depth: Vec<Name>,
@@ -102,12 +102,14 @@ impl TryFrom<MessageEvent> for WsMessage {
#[cfg(target_arch = "wasm32")]
#[derive(Debug)]
+/// Receiver for websocket frames. Implements `Readable` for asynchronous XML reading.
pub struct WebSocketOnMessageRead {
queue: mpsc::UnboundedReceiver<WsMessage>,
}
#[cfg(target_arch = "wasm32")]
impl WebSocketOnMessageRead {
+ /// Create a new `WebsocketOnMessageRead` with corresponding `on_message` event closure.
pub fn new() -> (Closure<dyn FnMut(MessageEvent)>, Self) {
let (send, recv) = mpsc::unbounded_channel();
let on_msg = Closure::wrap(Box::new(move |msg_evt: MessageEvent| {
@@ -148,6 +150,13 @@ impl Readable for WebSocketOnMessageRead {
}
}
+/// Trait for abstracting asynchronous read streams.
+pub trait Readable {
+ fn read_buf(&mut self, buffer: &mut Buffer)
+ -> impl std::future::Future<Output = Result<usize>>;
+}
+
+/// String wrapper which implements Readable, for string parsing.
pub struct ReadableString(pub String);
impl Readable for ReadableString {
@@ -157,12 +166,8 @@ impl Readable for ReadableString {
}
}
-pub trait Readable {
- fn read_buf(&mut self, buffer: &mut Buffer)
- -> impl std::future::Future<Output = Result<usize>>;
-}
-
impl<R> Reader<R> {
+ /// Create a new `Reader` which is constrained to a single root element.
pub fn new(reader: R) -> Self {
let mut default_declarations = HashSet::new();
default_declarations.insert(NamespaceDeclaration {
@@ -184,6 +189,7 @@ impl<R> Reader<R> {
}
}
+ /// Create a new `Reader` which is not constrained to a single root element.
pub fn new_unendable(reader: R) -> Self {
let mut default_declarations = HashSet::new();
default_declarations.insert(NamespaceDeclaration {
@@ -205,6 +211,7 @@ impl<R> Reader<R> {
}
}
+ /// Extract the inner type from the `Reader`.
pub fn into_inner(self) -> R {
self.inner
}
@@ -220,6 +227,7 @@ where
}
impl<R: Readable> Reader<R> {
+ /// Attempt to read an XML prolog, which could include an XML declaration, miscellaneous items (e.g. comments, processing instructions), and/or a doctype declaration.
pub async fn read_prolog<'s>(&'s mut self) -> Result<Option<Declaration>> {
if !self.unendable && self.root_ended {
return Err(Error::RootElementEnded);
@@ -275,18 +283,21 @@ impl<R: Readable> Reader<R> {
}
}
+ /// Read a start tag, moving up in document depth, and convert it into a type which implements `FromElement`.
pub async fn read_start<'s, T: FromElement>(&'s mut self) -> Result<T> {
let element = self.read_start_tag().await?;
trace!("read element start: {:?}", element);
Ok(FromElement::from_element(element)?)
}
+ /// Read a full element (start tag + content + end tag, or empty tag) and convert it into a type which implements `FromElement`.
pub async fn read<'s, T: FromElement>(&'s mut self) -> Result<T> {
let element = self.read_element().await?;
trace!("read element: {:?}", element);
Ok(FromElement::from_element(element)?)
}
+ /// Read a start tag, moving up in document depth.
pub async fn read_start_tag<'s>(&'s mut self) -> Result<Element> {
if !self.unendable && self.root_ended {
return Err(Error::RootElementEnded);
@@ -322,6 +333,7 @@ impl<R: Readable> Reader<R> {
}
}
+ /// Read an end tag, moving down in document depth.
pub async fn read_end_tag<'s>(&'s mut self) -> Result<()> {
if !self.unendable && self.root_ended {
return Err(Error::RootElementEnded);
@@ -360,6 +372,7 @@ impl<R: Readable> Reader<R> {
}
}
+ /// Read a full element (start tag + content + end tag, or empty tag).
pub async fn read_element<'s>(&'s mut self) -> Result<Element> {
if !self.unendable && self.root_ended {
return Err(Error::RootElementEnded);
@@ -395,6 +408,7 @@ impl<R: Readable> Reader<R> {
}
}
+ /// Read element content (text, another full element, a comment, a PI).
pub async fn read_content<'s>(&'s mut self) -> Result<Content> {
if !self.unendable && self.root_ended {
return Err(Error::RootElementEnded);
@@ -552,6 +566,7 @@ impl<R: Readable> Reader<R> {
}
impl<R> Reader<R> {
+ /// Convert a start tag into an `Element` given a mutable document context.
fn start_tag_from_xml(
depth: &mut Vec<Name>,
namespace_declarations: &mut Vec<HashSet<NamespaceDeclaration>>,
@@ -673,6 +688,7 @@ impl<R> Reader<R> {
});
}
+ /// Ensure an end tag is acceptable given a document context.
fn end_tag_from_xml(
depth: &mut Vec<Name>,
namespace_declarations: &mut Vec<HashSet<NamespaceDeclaration>>,
@@ -720,6 +736,7 @@ impl<R> Reader<R> {
}
}
+ /// Convert an xml element (empty or not) into an `Element` given a mutable document context.
fn element_from_xml(
namespace_declarations: &mut Vec<HashSet<NamespaceDeclaration>>,
element: xml::Element,
@@ -894,6 +911,7 @@ impl<R> Reader<R> {
});
}
+ /// Convert xml content into a `VecDeque` of `Content` given a document context.
fn content_from_xml(
namespaces: &mut Vec<HashSet<NamespaceDeclaration>>,
xml_content: xml::Content,