diff --git a/crates/proto-xmpp/src/bind.rs b/crates/proto-xmpp/src/bind.rs index d27a00e..d546141 100644 --- a/crates/proto-xmpp/src/bind.rs +++ b/crates/proto-xmpp/src/bind.rs @@ -74,8 +74,8 @@ impl Jid { pub struct BindRequest(pub Resource); impl FromXmlTag for BindRequest { - const NS: &'static str = XMLNS; const NAME: &'static str = "bind"; + const NS: &'static str = XMLNS; } impl FromXml for BindRequest { diff --git a/crates/proto-xmpp/src/lib.rs b/crates/proto-xmpp/src/lib.rs index d3e25ba..71e8a94 100644 --- a/crates/proto-xmpp/src/lib.rs +++ b/crates/proto-xmpp/src/lib.rs @@ -3,6 +3,7 @@ pub mod bind; pub mod client; pub mod disco; +pub mod mam; pub mod muc; mod prelude; pub mod roster; diff --git a/crates/proto-xmpp/src/mam.rs b/crates/proto-xmpp/src/mam.rs new file mode 100644 index 0000000..796a3d6 --- /dev/null +++ b/crates/proto-xmpp/src/mam.rs @@ -0,0 +1,71 @@ +use anyhow::{anyhow, Result}; +use quick_xml::events::Event; +use quick_xml::name::{Namespace, ResolveResult}; + +use crate::xml::*; + +pub const XMLNS: &'static str = "urn:xmpp:mam:2"; + +#[derive(PartialEq, Eq, Debug, Clone)] +pub struct MessageArchiveRequest; + +impl FromXmlTag for MessageArchiveRequest { + const NAME: &'static str = "query"; + const NS: &'static str = XMLNS; +} + +impl FromXml for MessageArchiveRequest { + type P = impl Parser>; + + fn parse() -> Self::P { + |(namespace, event): (ResolveResult<'static>, &'static Event<'static>)| -> Result { + let Event::Start(bytes) = event else { + return Err(anyhow!("Unexpected XML event: {event:?}")); + }; + if bytes.name().0 != MessageArchiveRequest::NAME.as_bytes() { + return Err(anyhow!("Unexpected XML tag: {:?}", bytes.name())); + } + let ResolveResult::Bound(Namespace(ns)) = namespace else { + return Err(anyhow!("No namespace provided")); + }; + if ns != XMLNS.as_bytes() { + return Err(anyhow!("Incorrect namespace")); + } + loop { + let (namespace, event) = yield; + match event { + Event::End(bytes) if bytes.name().0 == MessageArchiveRequest::NAME.as_bytes() => { + break; + } + _ => return Err(anyhow!("Unexpected XML event: {event:?}")), + } + } + Ok(MessageArchiveRequest) + } + } +} + +impl MessageArchiveRequest {} + +#[cfg(test)] +mod tests { + use super::*; + use crate::client::{Iq, IqType}; + + #[test] + fn test_parse() { + let input = r#""#; + + let result: Iq = parse(input).unwrap(); + assert_eq!( + result, + Iq { + from: None, + id: "mam_1".to_string(), + to: None, + r#type: IqType::Get, + body: MessageArchiveRequest, + } + ); + } +}