forked from lavina/lavina
93 lines
2.8 KiB
Rust
93 lines
2.8 KiB
Rust
use anyhow::anyhow;
|
|
use derive_more::From;
|
|
use quick_xml::events::Event;
|
|
use quick_xml::name::{Namespace, ResolveResult};
|
|
|
|
use lavina_core::prelude::*;
|
|
use proto_xmpp::bind::BindRequest;
|
|
use proto_xmpp::client::{Iq, Message, Presence};
|
|
use proto_xmpp::disco::{InfoQuery, ItemQuery};
|
|
use proto_xmpp::roster::RosterQuery;
|
|
use proto_xmpp::session::Session;
|
|
use proto_xmpp::xml::*;
|
|
|
|
#[derive(PartialEq, Eq, Debug, From)]
|
|
pub enum IqClientBody {
|
|
Bind(BindRequest),
|
|
Session(Session),
|
|
Roster(RosterQuery),
|
|
DiscoInfo(InfoQuery),
|
|
DiscoItem(ItemQuery),
|
|
Unknown(Ignore),
|
|
}
|
|
|
|
impl FromXml for IqClientBody {
|
|
type P = impl Parser<Output = Result<Self>>;
|
|
|
|
fn parse() -> Self::P {
|
|
|(namespace, event): (ResolveResult<'static>, &'static Event<'static>)| -> Result<Self> {
|
|
let bytes = match event {
|
|
Event::Start(bytes) => bytes,
|
|
Event::Empty(bytes) => bytes,
|
|
_ => return Err(anyhow!("Unexpected XML event: {event:?}")),
|
|
};
|
|
let name = bytes.name();
|
|
match_parser!(name, namespace, event;
|
|
BindRequest,
|
|
Session,
|
|
RosterQuery,
|
|
InfoQuery,
|
|
ItemQuery,
|
|
{
|
|
delegate_parsing!(Ignore, namespace, event).into()
|
|
}
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(PartialEq, Eq, Debug, From)]
|
|
pub enum ClientPacket {
|
|
Iq(Iq<IqClientBody>),
|
|
Message(Message<Ignore>),
|
|
Presence(Presence<Ignore>),
|
|
StreamEnd,
|
|
}
|
|
|
|
impl FromXml for ClientPacket {
|
|
type P = impl Parser<Output = Result<Self>>;
|
|
|
|
fn parse() -> Self::P {
|
|
|(namespace, event): (ResolveResult<'static>, &'static Event<'static>)| -> Result<Self> {
|
|
match event {
|
|
Event::Start(bytes) | Event::Empty(bytes) => {
|
|
let name = bytes.name();
|
|
match_parser!(name, namespace, event;
|
|
Iq::<IqClientBody>,
|
|
Presence::<Ignore>,
|
|
Message::<Ignore>,
|
|
{
|
|
Err(anyhow!(
|
|
"Unexpected XML event of name {:?} in namespace {:?}",
|
|
name,
|
|
namespace
|
|
))
|
|
}
|
|
)
|
|
}
|
|
Event::End(bytes) => {
|
|
let name = bytes.name();
|
|
if name.local_name().as_ref() == b"stream" {
|
|
return Ok(ClientPacket::StreamEnd);
|
|
} else {
|
|
return Err(anyhow!("Unexpected XML event: {event:?}"));
|
|
}
|
|
}
|
|
_ => {
|
|
return Err(anyhow!("Unexpected XML event: {event:?}"));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|