lavina/src/protos/xmpp/disco.rs

305 lines
9.4 KiB
Rust
Raw Normal View History

2023-03-27 21:45:44 +00:00
use quick_xml::events::Event;
use quick_xml::name::ResolveResult;
use crate::prelude::*;
use crate::util::xml::*;
use super::bind::Jid;
pub const XMLNS_INFO: &'static str = "http://jabber.org/protocol/disco#info";
pub const XMLNS_ITEM: &'static str = "http://jabber.org/protocol/disco#item";
2023-03-27 21:52:31 +00:00
#[derive(PartialEq, Eq, Debug)]
2023-03-27 21:45:44 +00:00
pub struct InfoQuery {
pub node: Option<String>,
pub identity: Vec<Identity>,
pub feature: Vec<Feature>,
}
impl FromXml for InfoQuery {
type P = impl Parser<Output = Result<Self>>;
fn parse() -> Self::P {
|(namespace, event): (ResolveResult<'static>, &'static Event<'static>)| -> Result<Self> {
let mut node = None;
let mut identity = vec![];
let mut feature = vec![];
let (bytes, end) = match event {
Event::Start(bytes) => (bytes, false),
Event::Empty(bytes) => (bytes, true),
_ => return Err(ffail!("Unexpected XML event: {event:?}")),
};
for attr in bytes.attributes() {
let attr = attr?;
match attr.key.0 {
b"node" => {
let s = std::str::from_utf8(bytes)?;
node = Some(s.to_owned())
}
_ => {}
}
}
if end {
2023-03-27 21:52:31 +00:00
return Ok(InfoQuery {
node,
identity,
feature,
});
2023-03-27 21:45:44 +00:00
}
loop {
let (namespace, event) = yield;
let bytes = match event {
Event::Start(bytes) => bytes,
Event::Empty(bytes) => bytes,
Event::End(_) => break,
_ => return Err(ffail!("Unexpected XML event: {event:?}")),
};
if bytes.name().0 == Identity::NAME.as_bytes() {
let res = delegate_parsing!(Identity, namespace, event)?;
identity.push(res);
} else if bytes.name().0 == Feature::NAME.as_bytes() {
let res = delegate_parsing!(Feature, namespace, event)?;
feature.push(res);
} else {
return Err(ffail!("Unexpected XML event: {event:?}"));
}
}
2023-03-27 21:52:31 +00:00
return Ok(InfoQuery {
node,
identity,
feature,
});
2023-03-27 21:45:44 +00:00
}
}
}
impl FromXmlTag for InfoQuery {
const NAME: &'static str = "query";
const NS: &'static str = XMLNS_INFO;
}
2023-03-27 21:52:31 +00:00
#[derive(PartialEq, Eq, Debug)]
2023-03-27 21:45:44 +00:00
pub struct Identity {
category: String,
name: Option<String>,
r#type: String,
}
impl FromXml for Identity {
type P = impl Parser<Output = Result<Self>>;
fn parse() -> Self::P {
|(namespace, event): (ResolveResult<'static>, &'static Event<'static>)| -> Result<Self> {
let mut category = None;
let mut name = None;
let mut r#type = None;
let (bytes, end) = match event {
Event::Start(bytes) => (bytes, false),
Event::Empty(bytes) => (bytes, true),
_ => return Err(ffail!("Unexpected XML event: {event:?}")),
};
for attr in bytes.attributes() {
let attr = attr?;
match attr.key.0 {
b"category" => {
let s = std::str::from_utf8(bytes)?;
category = Some(s.to_owned())
}
b"name" => {
let s = std::str::from_utf8(bytes)?;
name = Some(s.to_owned())
}
b"type" => {
let s = std::str::from_utf8(bytes)?;
r#type = Some(s.to_owned())
}
_ => {}
}
}
let Some(category) = category else {
return Err(ffail!("No jid provided"));
};
let Some(r#type) = r#type else {
return Err(ffail!("No type provided"));
};
2023-03-27 21:52:31 +00:00
let item = Identity {
category,
name,
r#type,
};
2023-03-27 21:45:44 +00:00
if end {
return Ok(item);
}
let (namespace, event) = yield;
let Event::End(bytes) = event else {
return Err(ffail!("Unexpected XML event: {event:?}"));
};
Ok(item)
}
}
}
impl FromXmlTag for Identity {
const NAME: &'static str = "identity";
const NS: &'static str = XMLNS_INFO;
}
2023-03-27 21:52:31 +00:00
#[derive(PartialEq, Eq, Debug)]
2023-03-27 21:45:44 +00:00
pub struct Feature {
pub var: String,
}
impl FromXml for Feature {
type P = impl Parser<Output = Result<Self>>;
fn parse() -> Self::P {
|(namespace, event): (ResolveResult<'static>, &'static Event<'static>)| -> Result<Self> {
let mut var = None;
let (bytes, end) = match event {
Event::Start(bytes) => (bytes, false),
Event::Empty(bytes) => (bytes, true),
_ => return Err(ffail!("Unexpected XML event: {event:?}")),
};
for attr in bytes.attributes() {
let attr = attr?;
match attr.key.0 {
b"var" => {
let s = std::str::from_utf8(bytes)?;
var = Some(s.to_owned())
}
_ => {}
}
}
let Some(var) = var else {
return Err(ffail!("No jid provided"));
};
let item = Feature { var };
if end {
return Ok(item);
}
let (namespace, event) = yield;
let Event::End(bytes) = event else {
return Err(ffail!("Unexpected XML event: {event:?}"));
};
Ok(item)
}
}
}
impl FromXmlTag for Feature {
const NAME: &'static str = "feature";
const NS: &'static str = XMLNS_INFO;
}
2023-03-27 21:52:31 +00:00
#[derive(PartialEq, Eq, Debug)]
2023-03-27 21:45:44 +00:00
pub struct ItemQuery {
pub item: Vec<Item>,
}
impl FromXml for ItemQuery {
type P = impl Parser<Output = Result<Self>>;
fn parse() -> Self::P {
|(namespace, event): (ResolveResult<'static>, &'static Event<'static>)| -> Result<Self> {
let mut item = vec![];
let (bytes, end) = match event {
Event::Start(bytes) => (bytes, false),
Event::Empty(bytes) => (bytes, true),
_ => return Err(ffail!("Unexpected XML event: {event:?}")),
};
if end {
2023-03-27 21:52:31 +00:00
return Ok(ItemQuery { item });
2023-03-27 21:45:44 +00:00
}
loop {
let (namespace, event) = yield;
let bytes = match event {
Event::Start(bytes) => bytes,
Event::Empty(bytes) => bytes,
Event::End(_) => break,
_ => return Err(ffail!("Unexpected XML event: {event:?}")),
};
if bytes.name().0 == Item::NAME.as_bytes() {
let res = delegate_parsing!(Item, namespace, event)?;
item.push(res);
} else {
return Err(ffail!("Unexpected XML event: {event:?}"));
}
}
Ok(ItemQuery { item })
}
}
}
impl FromXmlTag for ItemQuery {
const NAME: &'static str = "query";
const NS: &'static str = XMLNS_ITEM;
}
2023-03-27 21:52:31 +00:00
#[derive(PartialEq, Eq, Debug)]
2023-03-27 21:45:44 +00:00
pub struct Item {
pub jid: super::bind::Jid,
pub name: Option<String>,
pub node: Option<String>,
}
impl FromXml for Item {
type P = impl Parser<Output = Result<Self>>;
fn parse() -> Self::P {
|(namespace, event): (ResolveResult<'static>, &'static Event<'static>)| -> Result<Self> {
let mut jid = None;
let mut name = None;
let mut node = None;
let (bytes, end) = match event {
Event::Start(bytes) => (bytes, false),
Event::Empty(bytes) => (bytes, true),
_ => return Err(ffail!("Unexpected XML event: {event:?}")),
};
for attr in bytes.attributes() {
let attr = attr?;
match attr.key.0 {
b"name" => {
let s = std::str::from_utf8(bytes)?;
name = Some(s.to_owned())
}
b"node" => {
let s = std::str::from_utf8(bytes)?;
node = Some(s.to_owned())
}
b"jid" => {
let s = std::str::from_utf8(bytes)?;
let s = Jid::from_string(s)?;
jid = Some(s)
}
_ => {}
}
}
let Some(jid) = jid else {
return Err(ffail!("No jid provided"));
};
let item = Item { jid, name, node };
if end {
return Ok(item);
}
let (namespace, event) = yield;
let Event::End(bytes) = event else {
return Err(ffail!("Unexpected XML event: {event:?}"));
};
Ok(item)
}
}
}
impl FromXmlTag for Item {
const NAME: &'static str = "item";
const NS: &'static str = XMLNS_ITEM;
2023-03-27 21:52:31 +00:00
}