diff options
Diffstat (limited to '')
-rw-r--r-- | src/stanza/iq.rs | 169 |
1 files changed, 0 insertions, 169 deletions
diff --git a/src/stanza/iq.rs b/src/stanza/iq.rs index 6c7dee3..8b13789 100644 --- a/src/stanza/iq.rs +++ b/src/stanza/iq.rs @@ -1,170 +1 @@ -use nanoid::nanoid; -use quick_xml::{ - events::{BytesStart, Event}, - name::QName, - Reader, Writer, -}; -use crate::{JabberClient, JabberError, JID}; - -use crate::Result; - -#[derive(Debug)] -pub struct IQ { - to: Option<JID>, - from: Option<JID>, - id: String, - r#type: IQType, - lang: Option<String>, - child: Element<'static>, -} - -#[derive(Debug)] -enum IQType { - Get, - Set, - Result, - Error, -} - -impl IQ { - pub async fn set<'j, R: IntoElement<'static>>( - client: &mut JabberClient<'j>, - to: Option<JID>, - from: Option<JID>, - element: R, - ) -> Result<Element<'static>> { - let id = nanoid!(); - let iq = IQ { - to, - from, - id: id.clone(), - r#type: IQType::Set, - lang: None, - child: Element::from(element), - }; - println!("{:?}", iq); - let iq = Element::from(iq); - println!("{:?}", iq); - iq.write(&mut client.writer).await?; - let result = Element::read(&mut client.reader).await?; - let iq = IQ::try_from(result)?; - if iq.id == id { - return Ok(iq.child); - } - Err(JabberError::IDMismatch) - } -} - -impl<'e> IntoElement<'e> for IQ { - fn event(&self) -> quick_xml::events::Event<'e> { - let mut start = BytesStart::new("iq"); - if let Some(to) = &self.to { - start.push_attribute(("to", to.to_string().as_str())); - } - if let Some(from) = &self.from { - start.push_attribute(("from", from.to_string().as_str())); - } - start.push_attribute(("id", self.id.as_str())); - match self.r#type { - IQType::Get => start.push_attribute(("type", "get")), - IQType::Set => start.push_attribute(("type", "set")), - IQType::Result => start.push_attribute(("type", "result")), - IQType::Error => start.push_attribute(("type", "error")), - } - if let Some(lang) = &self.lang { - start.push_attribute(("from", lang.to_string().as_str())); - } - - quick_xml::events::Event::Start(start) - } - - fn children(&self) -> Option<Vec<Element<'e>>> { - Some(vec![self.child.clone()]) - } -} - -impl TryFrom<Element<'static>> for IQ { - type Error = JabberError; - - fn try_from(element: Element<'static>) -> std::result::Result<Self, Self::Error> { - if let Event::Start(start) = &element.event { - if start.name() == QName(b"iq") { - let mut to: Option<JID> = None; - let mut from: Option<JID> = None; - let mut id = None; - let mut r#type = None; - let mut lang = None; - start - .attributes() - .into_iter() - .try_for_each(|attribute| -> Result<()> { - if let Ok(attribute) = attribute { - let buf: Vec<u8> = Vec::new(); - let reader = Reader::from_reader(buf); - match attribute.key { - QName(b"to") => { - to = Some( - attribute - .decode_and_unescape_value(&reader) - .or(Err(JabberError::Utf8Decode))? - .into_owned() - .try_into()?, - ) - } - QName(b"from") => { - from = Some( - attribute - .decode_and_unescape_value(&reader) - .or(Err(JabberError::Utf8Decode))? - .into_owned() - .try_into()?, - ) - } - QName(b"id") => { - id = Some( - attribute - .decode_and_unescape_value(&reader) - .or(Err(JabberError::Utf8Decode))? - .into_owned(), - ) - } - QName(b"type") => { - let value = attribute - .decode_and_unescape_value(&reader) - .or(Err(JabberError::Utf8Decode))?; - match value.as_ref() { - "get" => r#type = Some(IQType::Get), - "set" => r#type = Some(IQType::Set), - "result" => r#type = Some(IQType::Result), - "error" => r#type = Some(IQType::Error), - _ => return Err(JabberError::ParseError), - } - } - QName(b"lang") => { - lang = Some( - attribute - .decode_and_unescape_value(&reader) - .or(Err(JabberError::Utf8Decode))? - .into_owned(), - ) - } - _ => return Err(JabberError::UnknownAttribute), - } - } - Ok(()) - })?; - let iq = IQ { - to, - from, - id: id.ok_or(JabberError::NoID)?, - r#type: r#type.ok_or(JabberError::NoType)?, - lang, - child: element.child()?.to_owned(), - }; - return Ok(iq); - } - } - Err(JabberError::ParseError) - } -} |