lavina/src/protos/xmpp/stream.rs

65 lines
2.6 KiB
Rust
Raw Normal View History

use quick_xml::name::{ResolveResult, Namespace, LocalName, QName};
use quick_xml::{Result, NsReader};
use quick_xml::events::Event;
use tokio::io::AsyncBufRead;
pub static XMLNS: &'static str = "http://etherx.jabber.org/streams";
#[derive(Debug, PartialEq, Eq)]
pub struct ClientStreamStart {
pub to: String,
pub lang: String,
pub version: String,
}
impl ClientStreamStart {
pub async fn parse(reader: &mut NsReader<impl AsyncBufRead + Unpin>, buf: &mut Vec<u8>) -> Result<ClientStreamStart> {
if let Event::Start(e) = reader.read_event_into_async(buf).await? {
let (ns, local) = reader.resolve_element(e.name());
if ns != ResolveResult::Bound(Namespace(XMLNS.as_bytes())) {
return Err(panic!());
}
if local.into_inner() != b"stream" {
return Err(panic!());
}
let mut to = None;
let mut lang = None;
let mut version = None;
for attr in e.attributes() {
let attr = attr?;
let (ns, name) = reader.resolve_attribute(attr.key);
match (ns, name.into_inner()) {
(ResolveResult::Unbound, b"to") => {
let value = attr.unescape_value()?;
to = Some(value.to_string());
},
(ResolveResult::Bound(Namespace(b"http://www.w3.org/XML/1998/namespace")), b"lang") => {
let value = attr.unescape_value()?;
lang = Some(value.to_string());
},
(ResolveResult::Unbound, b"version") => {
let value = attr.unescape_value()?;
version = Some(value.to_string());
},
_ => {},
}
}
Ok(ClientStreamStart { to: to.unwrap(), lang: lang.unwrap(), version: version.unwrap() })
} else {
Err(panic!())
}
}
}
#[cfg(test)]
mod test {
use super::*;
#[tokio::test]
async fn stream_start_correct() {
let input = r###"<stream:stream xmlns:stream="http://etherx.jabber.org/streams" to="vlnv.dev" version="1.0" xmlns="jabber:client" xml:lang="en" xmlns:xml="http://www.w3.org/XML/1998/namespace">"###;
let mut reader = NsReader::from_reader(input.as_bytes());
let mut buf = vec![];
let res = ClientStreamStart::parse(&mut reader, &mut buf).await.unwrap();
assert_eq!(res, ClientStreamStart { to: "vlnv.dev".to_owned(), lang: "en".to_owned(), version: "1.0".to_owned()})
}
}