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, pub maxstanzas: Option, pub seconds: Option, } impl FromXml for History { type P = impl Parser>; fn parse() -> Self::P { |(namespace, event): (ResolveResult<'static>, &'static Event<'static>)| -> Result { 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>; fn parse() -> Self::P { |(namespace, event): (ResolveResult<'static>, &'static Event<'static>)| -> Result { 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, pub password: Option, } impl FromXml for X { type P = impl Parser>; fn parse() -> Self::P { |(namespace, event): (ResolveResult<'static>, &'static Event<'static>)| -> Result { 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) } } }