forked from lavina/lavina
80 lines
2.4 KiB
Rust
80 lines
2.4 KiB
Rust
use quick_xml::events::{BytesStart, Event};
|
|
|
|
use crate::xml::*;
|
|
use anyhow::{anyhow, Result};
|
|
use quick_xml::name::{Namespace, ResolveResult};
|
|
|
|
pub const XMLNS: &'static str = "jabber:iq:roster";
|
|
|
|
#[derive(PartialEq, Eq, Debug)]
|
|
pub struct RosterQuery;
|
|
|
|
impl FromXml for RosterQuery {
|
|
type P = impl Parser<Output = Result<Self>>;
|
|
|
|
fn parse() -> Self::P {
|
|
|(mut namespace, mut event): (ResolveResult<'static>, &'static Event<'static>)| -> Result<Self> {
|
|
let ResolveResult::Bound(Namespace(ns)) = namespace else {
|
|
return Err(anyhow!("No namespace provided"));
|
|
};
|
|
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:?}")),
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
impl FromXmlTag for RosterQuery {
|
|
const NAME: &'static str = "query";
|
|
const NS: &'static str = XMLNS;
|
|
}
|
|
|
|
impl ToXml for RosterQuery {
|
|
fn serialize(&self, events: &mut Vec<Event<'static>>) {
|
|
events.push(Event::Empty(BytesStart::new(format!(r#"query xmlns="{}""#, XMLNS))));
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use crate::bind::{Jid, Name, Resource, Server};
|
|
use crate::client::{Iq, IqType};
|
|
|
|
#[test]
|
|
fn test_parse() {
|
|
let input =
|
|
r#"<iq from='juliet@example.com/balcony' id='bv1bs71f' type='get'><query xmlns='jabber:iq:roster'/></iq>"#;
|
|
|
|
let result: Iq<RosterQuery> = parse(input).unwrap();
|
|
assert_eq!(
|
|
result,
|
|
Iq {
|
|
from: Option::from(Jid {
|
|
name: Option::from(Name("juliet".into())),
|
|
server: Server("example.com".into()),
|
|
resource: Option::from(Resource("balcony".into())),
|
|
}),
|
|
id: "bv1bs71f".to_string(),
|
|
to: None,
|
|
r#type: IqType::Get,
|
|
body: RosterQuery,
|
|
}
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn test_missing_namespace() {
|
|
let input = r#"<iq from='juliet@example.com/balcony' id='bv1bs71f' type='get'><query/></iq>"#;
|
|
|
|
assert!(parse::<Iq<RosterQuery>>(input).is_err());
|
|
}
|
|
}
|