forked from lavina/lavina
xmpp: rewrite xml element parsers using coroutines
This commit is contained in:
parent
048660624d
commit
fbb3d4f4f9
|
@ -1,47 +1,30 @@
|
|||
use quick_xml::events::{BytesStart, Event};
|
||||
|
||||
use crate::xml::*;
|
||||
use anyhow::{anyhow as ffail, Result};
|
||||
use anyhow::{anyhow, Result};
|
||||
use quick_xml::name::ResolveResult;
|
||||
|
||||
pub const XMLNS: &'static str = "jabber:iq:roster";
|
||||
|
||||
#[derive(PartialEq, Eq, Debug)]
|
||||
pub struct RosterQuery;
|
||||
|
||||
pub struct QueryParser(QueryParserInner);
|
||||
|
||||
enum QueryParserInner {
|
||||
Initial,
|
||||
InQuery,
|
||||
}
|
||||
|
||||
impl Parser for QueryParser {
|
||||
type Output = Result<RosterQuery>;
|
||||
|
||||
fn consume<'a>(
|
||||
self: Self,
|
||||
namespace: quick_xml::name::ResolveResult,
|
||||
event: &quick_xml::events::Event<'a>,
|
||||
) -> Continuation<Self, Self::Output> {
|
||||
match self.0 {
|
||||
QueryParserInner::Initial => match event {
|
||||
Event::Start(_) => Continuation::Continue(QueryParser(QueryParserInner::InQuery)),
|
||||
Event::Empty(_) => Continuation::Final(Ok(RosterQuery)),
|
||||
_ => Continuation::Final(Err(ffail!("Unexpected XML event: {event:?}"))),
|
||||
},
|
||||
QueryParserInner::InQuery => match event {
|
||||
Event::End(_) => Continuation::Final(Ok(RosterQuery)),
|
||||
_ => Continuation::Final(Err(ffail!("Unexpected XML event: {event:?}"))),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromXml for RosterQuery {
|
||||
type P = QueryParser;
|
||||
type P = impl Parser<Output = Result<Self>>;
|
||||
|
||||
fn parse() -> Self::P {
|
||||
QueryParser(QueryParserInner::Initial)
|
||||
|(mut namespace, mut event): (ResolveResult<'static>, &'static Event<'static>)| -> Result<Self> {
|
||||
match event {
|
||||
Event::Start(_) => (),
|
||||
Event::Empty(_) => return Ok(RosterQuery),
|
||||
_ => return Err(anyhow!("Unexpected XML event: {event:?}")),
|
||||
}
|
||||
(namespace, event) = yield;
|
||||
match event {
|
||||
Event::End(_) => return Ok(RosterQuery),
|
||||
_ => return Err(anyhow!("Unexpected XML event: {event:?}")),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,46 +2,29 @@ use quick_xml::events::{BytesStart, Event};
|
|||
|
||||
use crate::xml::*;
|
||||
use anyhow::{anyhow, Result};
|
||||
use quick_xml::name::ResolveResult;
|
||||
|
||||
pub const XMLNS: &'static str = "urn:ietf:params:xml:ns:xmpp-session";
|
||||
|
||||
#[derive(PartialEq, Eq, Debug)]
|
||||
pub struct Session;
|
||||
|
||||
pub struct SessionParser(SessionParserInner);
|
||||
|
||||
enum SessionParserInner {
|
||||
Initial,
|
||||
InSession,
|
||||
}
|
||||
|
||||
impl Parser for SessionParser {
|
||||
type Output = Result<Session>;
|
||||
|
||||
fn consume<'a>(
|
||||
self: Self,
|
||||
namespace: quick_xml::name::ResolveResult,
|
||||
event: &quick_xml::events::Event<'a>,
|
||||
) -> Continuation<Self, Self::Output> {
|
||||
match self.0 {
|
||||
SessionParserInner::Initial => match event {
|
||||
Event::Start(_) => Continuation::Continue(SessionParser(SessionParserInner::InSession)),
|
||||
Event::Empty(_) => Continuation::Final(Ok(Session)),
|
||||
_ => Continuation::Final(Err(anyhow!("Unexpected XML event: {event:?}"))),
|
||||
},
|
||||
SessionParserInner::InSession => match event {
|
||||
Event::End(_) => Continuation::Final(Ok(Session)),
|
||||
_ => Continuation::Final(Err(anyhow!("Unexpected XML event: {event:?}"))),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromXml for Session {
|
||||
type P = SessionParser;
|
||||
type P = impl Parser<Output = Result<Self>>;
|
||||
|
||||
fn parse() -> Self::P {
|
||||
SessionParser(SessionParserInner::Initial)
|
||||
|(mut namespace, mut event): (ResolveResult<'static>, &'static Event<'static>)| -> Result<Self> {
|
||||
match event {
|
||||
Event::Start(_) => (),
|
||||
Event::Empty(_) => return Ok(Session),
|
||||
_ => return Err(anyhow!("Unexpected XML event: {event:?}")),
|
||||
}
|
||||
(namespace, event) = yield;
|
||||
match event {
|
||||
Event::End(_) => return Ok(Session),
|
||||
_ => return Err(anyhow!("Unexpected XML event: {event:?}")),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,49 +1,35 @@
|
|||
use super::*;
|
||||
use derive_more::From;
|
||||
|
||||
#[derive(Default, Debug, PartialEq, Eq)]
|
||||
pub struct Ignore;
|
||||
|
||||
#[derive(From)]
|
||||
pub struct IgnoreParser(IgnoreParserInner);
|
||||
|
||||
enum IgnoreParserInner {
|
||||
Initial,
|
||||
InTag { name: Vec<u8>, depth: u8 },
|
||||
}
|
||||
|
||||
impl Parser for IgnoreParser {
|
||||
type Output = Result<Ignore>;
|
||||
|
||||
fn consume<'a>(self: Self, _: ResolveResult, event: &Event<'a>) -> Continuation<Self, Self::Output> {
|
||||
match self.0 {
|
||||
IgnoreParserInner::Initial => match event {
|
||||
Event::Start(bytes) => {
|
||||
let name = bytes.name().0.to_owned();
|
||||
Continuation::Continue(IgnoreParserInner::InTag { name, depth: 0 }.into())
|
||||
}
|
||||
Event::Empty(_) => Continuation::Final(Ok(Ignore)),
|
||||
_ => Continuation::Final(Ok(Ignore)),
|
||||
},
|
||||
IgnoreParserInner::InTag { name, depth } => match event {
|
||||
Event::End(bytes) if name == bytes.name().0 => {
|
||||
if depth == 0 {
|
||||
Continuation::Final(Ok(Ignore))
|
||||
} else {
|
||||
Continuation::Continue(IgnoreParserInner::InTag { name, depth: depth - 1 }.into())
|
||||
}
|
||||
}
|
||||
_ => Continuation::Continue(IgnoreParserInner::InTag { name, depth }.into()),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromXml for Ignore {
|
||||
type P = IgnoreParser;
|
||||
type P = impl Parser<Output = Result<Self>>;
|
||||
|
||||
fn parse() -> Self::P {
|
||||
IgnoreParserInner::Initial.into()
|
||||
|(mut namespace, mut event): (ResolveResult<'static>, &'static Event<'static>)| -> Result<Self> {
|
||||
let mut depth = match event {
|
||||
Event::Start(bytes) => 0,
|
||||
Event::Empty(_) => return Ok(Ignore),
|
||||
_ => return Ok(Ignore),
|
||||
};
|
||||
loop {
|
||||
(namespace, event) = yield;
|
||||
match event {
|
||||
Event::End(_) => {
|
||||
if depth == 0 {
|
||||
return Ok(Ignore);
|
||||
} else {
|
||||
depth -= 1;
|
||||
}
|
||||
}
|
||||
Event::Start(_) => {
|
||||
depth += 1;
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue