forked from lavina/lavina
feat(xmpp): implement muc base element parsing
This commit is contained in:
parent
a73bbdb5f1
commit
0e78f24fbd
|
@ -1,5 +1,6 @@
|
|||
pub mod bind;
|
||||
pub mod client;
|
||||
pub mod muc;
|
||||
pub mod roster;
|
||||
pub mod sasl;
|
||||
pub mod session;
|
||||
|
|
|
@ -0,0 +1,160 @@
|
|||
use quick_xml::events::Event;
|
||||
use quick_xml::name::ResolveResult;
|
||||
|
||||
use crate::prelude::*;
|
||||
use crate::util::xml::*;
|
||||
|
||||
pub const XMLNS: &'static str = "http://jabber.org/protocol/muc";
|
||||
|
||||
#[derive(PartialEq, Eq, Debug, Default)]
|
||||
pub struct History {
|
||||
pub maxchars: Option<u32>,
|
||||
pub maxstanzas: Option<u32>,
|
||||
pub seconds: Option<u32>,
|
||||
}
|
||||
|
||||
impl FromXml for History {
|
||||
type P = impl Parser<Output = Result<Self>>;
|
||||
|
||||
fn parse() -> Self::P {
|
||||
|(namespace, event): (ResolveResult<'static>, &'static Event<'static>)| -> Result<Self> {
|
||||
let mut history = History::default();
|
||||
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"maxchars" => {
|
||||
let s = std::str::from_utf8(bytes)?;
|
||||
let a = s.parse()?;
|
||||
history.maxchars = Some(a)
|
||||
}
|
||||
b"maxstanzas" => {
|
||||
let s = std::str::from_utf8(bytes)?;
|
||||
let a = s.parse()?;
|
||||
history.maxstanzas = Some(a)
|
||||
}
|
||||
b"seconds" => {
|
||||
let s = std::str::from_utf8(bytes)?;
|
||||
let a = s.parse()?;
|
||||
history.seconds = Some(a)
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
if end {
|
||||
return Ok(history);
|
||||
}
|
||||
|
||||
let (namespace, event) = yield;
|
||||
let Event::End(bytes) = event else {
|
||||
return Err(ffail!("Unexpected XML event: {event:?}"));
|
||||
};
|
||||
Ok(history)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromXmlTag for History {
|
||||
const NAME: &'static str = "history";
|
||||
|
||||
const NS: &'static str = XMLNS;
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Debug)]
|
||||
pub struct Password(pub String);
|
||||
|
||||
impl FromXml for Password {
|
||||
type P = impl Parser<Output = Result<Self>>;
|
||||
|
||||
fn parse() -> Self::P {
|
||||
|(namespace, event): (ResolveResult<'static>, &'static Event<'static>)| -> Result<Self> {
|
||||
let Event::Start(bytes) = event else {
|
||||
return Err(ffail!("Unexpected XML event: {event:?}"));
|
||||
};
|
||||
let (namespace, event) = yield;
|
||||
let Event::Text(bytes) = event else {
|
||||
return Err(ffail!("Unexpected XML event: {event:?}"));
|
||||
};
|
||||
let s = std::str::from_utf8(bytes)?.to_string();
|
||||
let Event::End(bytes) = event else {
|
||||
return Err(ffail!("Unexpected XML event: {event:?}"));
|
||||
};
|
||||
Ok(Password(s))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromXmlTag for Password {
|
||||
const NAME: &'static str = "password";
|
||||
|
||||
const NS: &'static str = XMLNS;
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Debug, Default)]
|
||||
pub struct X {
|
||||
pub history: Option<History>,
|
||||
pub password: Option<Password>,
|
||||
}
|
||||
|
||||
impl FromXml for X {
|
||||
type P = impl Parser<Output = Result<Self>>;
|
||||
|
||||
fn parse() -> Self::P {
|
||||
|(namespace, event): (ResolveResult<'static>, &'static Event<'static>)| -> Result<Self> {
|
||||
let mut res = X::default();
|
||||
let (bytes, end) = match event {
|
||||
Event::Start(bytes) => (bytes, false),
|
||||
Event::Empty(bytes) => (bytes, true),
|
||||
_ => return Err(ffail!("Unexpected XML event: {event:?}")),
|
||||
};
|
||||
if end {
|
||||
return Ok(res);
|
||||
}
|
||||
|
||||
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 == Password::NAME.as_bytes() {
|
||||
let mut parser = Password::parse().consume(namespace, event);
|
||||
let password = loop {
|
||||
match parser {
|
||||
Continuation::Final(Ok(res)) => break Ok(res),
|
||||
Continuation::Final(Err(err)) => break Err(err),
|
||||
Continuation::Continue(p) => {
|
||||
let (namespace, event) = yield;
|
||||
parser = p.consume(namespace, event);
|
||||
}
|
||||
}
|
||||
}?;
|
||||
res.password = Some(password);
|
||||
} else if bytes.name().0 == History::NAME.as_bytes() {
|
||||
let mut parser = History::parse().consume(namespace, event);
|
||||
let history = loop {
|
||||
match parser {
|
||||
Continuation::Final(Ok(res)) => break Ok(res),
|
||||
Continuation::Final(Err(err)) => break Err(err),
|
||||
Continuation::Continue(p) => {
|
||||
let (namespace, event) = yield;
|
||||
parser = p.consume(namespace, event);
|
||||
}
|
||||
}
|
||||
}?;
|
||||
res.history = Some(history);
|
||||
} else {
|
||||
return Err(ffail!("Unexpected XML event: {event:?}"));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(res)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue