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::util::xml::{Continuation, FromXml, Parser}; use crate::prelude::*; #[derive(PartialEq, Eq, Debug, From)] pub enum IqClientBody { Bind(BindRequest), } #[derive(From)] pub struct IqClientBodyParser(IqClientBodyParserInner); #[derive(From)] enum IqClientBodyParserInner { Initial, Bind(::P), } impl FromXml for IqClientBody { type P = IqClientBodyParser; fn parse() -> Self::P { IqClientBodyParserInner::Initial.into() } } impl Parser for IqClientBodyParser { type Output = Result; fn consume<'a>( self: Self, namespace: quick_xml::name::ResolveResult, event: &quick_xml::events::Event<'a>, ) -> crate::util::xml::Continuation { use IqClientBodyParserInner::*; match self.0 { Initial => { let Event::Start(bytes) = event else { return Continuation::Final(Err(ffail!("Unexpected XML event: {event:?}. Expected start of {}", BindRequest::NAME))); }; if bytes.name().0 == BindRequest::NAME.as_bytes() && namespace == ResolveResult::Bound(Namespace(BindRequest::NS.as_bytes())) { match BindRequest::parse().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()) } } } 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()) } }, } } } #[derive(PartialEq, Eq, Debug, From)] pub enum ClientPacket { Iq(Iq), 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( as FromXml>::P), Message(::P), } impl Parser for ClientPacketParser { type Output = Result; fn consume<'a>( self: Self, namespace: ResolveResult, event: &Event<'a>, ) -> Continuation { 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::::NAME.as_bytes() && namespace == ResolveResult::Bound(Namespace(Iq::::NS.as_bytes())) { ClientPacketParser(IqV(Iq::::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()) } }, } } }