forked from lavina/lavina
156 lines
5.5 KiB
Rust
156 lines
5.5 KiB
Rust
use derive_more::From;
|
|
use quick_xml::events::Event;
|
|
use quick_xml::name::{Namespace, ResolveResult};
|
|
|
|
use crate::protos::xmpp::bind::BindRequest;
|
|
use crate::protos::xmpp::client::{Iq, Message};
|
|
use crate::protos::xmpp::session::Session;
|
|
use crate::util::xml::{Continuation, FromXml, FromXmlTag, Parser};
|
|
|
|
use crate::prelude::*;
|
|
|
|
#[derive(PartialEq, Eq, Debug, From)]
|
|
pub enum IqClientBody {
|
|
Bind(BindRequest),
|
|
Session(Session),
|
|
}
|
|
|
|
#[derive(From)]
|
|
pub struct IqClientBodyParser(IqClientBodyParserInner);
|
|
|
|
#[derive(From)]
|
|
enum IqClientBodyParserInner {
|
|
Initial,
|
|
Bind(<BindRequest as FromXml>::P),
|
|
SessionV(<Session as FromXml>::P),
|
|
}
|
|
|
|
impl FromXml for IqClientBody {
|
|
type P = IqClientBodyParser;
|
|
|
|
fn parse() -> Self::P {
|
|
IqClientBodyParserInner::Initial.into()
|
|
}
|
|
}
|
|
|
|
impl Parser for IqClientBodyParser {
|
|
type Output = Result<IqClientBody>;
|
|
|
|
fn consume<'a>(
|
|
self: Self,
|
|
namespace: quick_xml::name::ResolveResult,
|
|
event: &quick_xml::events::Event<'a>,
|
|
) -> crate::util::xml::Continuation<Self, Self::Output> {
|
|
use IqClientBodyParserInner::*;
|
|
match self.0 {
|
|
Initial => {
|
|
let bytes = match event {
|
|
Event::Start(bytes) => bytes,
|
|
Event::Empty(bytes) => bytes,
|
|
_ => {
|
|
return Continuation::Final(Err(ffail!("Unexpected XML event: {event:?}")))
|
|
}
|
|
};
|
|
if bytes.name().0 == BindRequest::NAME.as_bytes()
|
|
&& namespace == ResolveResult::Bound(Namespace(BindRequest::NS.as_bytes()))
|
|
{
|
|
IqClientBodyParser(BindRequest::parse().into()).consume(namespace, event)
|
|
} else if bytes.name().0 == Session::NAME.as_bytes()
|
|
&& namespace == ResolveResult::Bound(Namespace(Session::NS.as_bytes()))
|
|
{
|
|
IqClientBodyParser(Session::parse().into()).consume(namespace, event)
|
|
} else {
|
|
Continuation::Final(Err(ffail!("Unexpected XML event: {event:?}")))
|
|
}
|
|
}
|
|
Bind(p) => match p.consume(namespace, event) {
|
|
Continuation::Final(Ok(r)) => Continuation::Final(Ok(r.into())),
|
|
Continuation::Final(Err(e)) => Continuation::Final(Err(e)),
|
|
Continuation::Continue(s) => {
|
|
let inner: IqClientBodyParserInner = s.into();
|
|
Continuation::Continue(inner.into())
|
|
}
|
|
},
|
|
SessionV(p) => match p.consume(namespace, event) {
|
|
Continuation::Final(Ok(r)) => Continuation::Final(Ok(r.into())),
|
|
Continuation::Final(Err(e)) => Continuation::Final(Err(e)),
|
|
Continuation::Continue(s) => {
|
|
let inner: IqClientBodyParserInner = s.into();
|
|
Continuation::Continue(inner.into())
|
|
}
|
|
},
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(PartialEq, Eq, Debug, From)]
|
|
pub enum ClientPacket {
|
|
Iq(Iq<IqClientBody>),
|
|
Message(Message),
|
|
}
|
|
|
|
#[derive(From)]
|
|
pub struct ClientPacketParser(ClientPacketParserInner);
|
|
|
|
impl FromXml for ClientPacket {
|
|
type P = ClientPacketParser;
|
|
|
|
fn parse() -> Self::P {
|
|
ClientPacketParserInner::Initial.into()
|
|
}
|
|
}
|
|
|
|
#[derive(From)]
|
|
enum ClientPacketParserInner {
|
|
Initial,
|
|
Iq(<Iq<IqClientBody> as FromXml>::P),
|
|
Message(<Message as FromXml>::P),
|
|
}
|
|
|
|
impl Parser for ClientPacketParser {
|
|
type Output = Result<ClientPacket>;
|
|
|
|
fn consume<'a>(
|
|
self: Self,
|
|
namespace: ResolveResult,
|
|
event: &Event<'a>,
|
|
) -> Continuation<Self, Self::Output> {
|
|
use ClientPacketParserInner::{Initial, Iq as IqV, Message as MessageV};
|
|
match self.0 {
|
|
Initial => {
|
|
let Event::Start(bytes) = event else {
|
|
return Continuation::Final(Err(ffail!("Unexpected XML event: {event:?}")));
|
|
};
|
|
if bytes.name().0 == Iq::<IqClientBody>::NAME.as_bytes()
|
|
&& namespace
|
|
== ResolveResult::Bound(Namespace(Iq::<IqClientBody>::NS.as_bytes()))
|
|
{
|
|
ClientPacketParser(IqV(Iq::<IqClientBody>::parse())).consume(namespace, event)
|
|
} else if bytes.name().0 == Message::NAME.as_bytes()
|
|
&& namespace == ResolveResult::Bound(Namespace(Message::NS.as_bytes()))
|
|
{
|
|
ClientPacketParser(MessageV(Message::parse())).consume(namespace, event)
|
|
} else {
|
|
Continuation::Final(Err(ffail!("Unexpected XML event: {event:?}")))
|
|
}
|
|
}
|
|
IqV(p) => match p.consume(namespace, event) {
|
|
Continuation::Final(Ok(r)) => Continuation::Final(Ok(r.into())),
|
|
Continuation::Final(Err(e)) => Continuation::Final(Err(e)),
|
|
Continuation::Continue(s) => {
|
|
let inner: ClientPacketParserInner = s.into();
|
|
Continuation::Continue(inner.into())
|
|
}
|
|
},
|
|
MessageV(p) => match p.consume(namespace, event) {
|
|
Continuation::Final(Ok(r)) => Continuation::Final(Ok(r.into())),
|
|
Continuation::Final(Err(e)) => Continuation::Final(Err(e)),
|
|
Continuation::Continue(s) => {
|
|
let inner: ClientPacketParserInner = s.into();
|
|
Continuation::Continue(inner.into())
|
|
}
|
|
},
|
|
}
|
|
}
|
|
}
|