diff options
Diffstat (limited to 'src/stanza/starttls.rs')
-rw-r--r-- | src/stanza/starttls.rs | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/src/stanza/starttls.rs b/src/stanza/starttls.rs index 8b13789..874ae66 100644 --- a/src/stanza/starttls.rs +++ b/src/stanza/starttls.rs @@ -1 +1,163 @@ +use std::collections::{HashMap, HashSet}; +use peanuts::{ + element::{Content, FromElement, IntoElement, Name, NamespaceDeclaration}, + Element, +}; + +pub const XMLNS: &str = "urn:ietf:params:xml:ns:xmpp-tls"; + +#[derive(Debug)] +pub struct StartTls { + pub required: bool, +} + +impl IntoElement for StartTls { + fn into_element(&self) -> peanuts::Element { + let content; + if self.required == true { + let element = Content::Element(Element { + name: Name { + namespace: Some(XMLNS.to_string()), + local_name: "required".to_string(), + }, + namespace_declarations: HashSet::new(), + attributes: HashMap::new(), + content: Vec::new(), + }); + content = vec![element]; + } else { + content = Vec::new(); + } + let mut namespace_declarations = HashSet::new(); + namespace_declarations.insert(NamespaceDeclaration { + prefix: None, + namespace: XMLNS.to_string(), + }); + Element { + name: Name { + namespace: Some(XMLNS.to_string()), + local_name: "starttls".to_string(), + }, + namespace_declarations, + attributes: HashMap::new(), + content, + } + } +} + +impl FromElement for StartTls { + fn from_element(element: peanuts::Element) -> peanuts::Result<Self> { + let Name { + namespace, + local_name, + } = element.name; + if namespace.as_deref() == Some(XMLNS) && &local_name == "starttls" { + let mut required = false; + if element.content.len() == 1 { + match element.content.first().unwrap() { + Content::Element(element) => { + let Name { + namespace, + local_name, + } = &element.name; + + if namespace.as_deref() == Some(XMLNS) && local_name == "required" { + required = true + } else { + return Err(peanuts::Error::UnexpectedElement(element.name.clone())); + } + } + c => return Err(peanuts::Error::UnexpectedContent((*c).clone())), + } + } else { + return Err(peanuts::Error::UnexpectedNumberOfContents( + element.content.len(), + )); + } + return Ok(StartTls { required }); + } else { + return Err(peanuts::Error::IncorrectName(Name { + namespace, + local_name, + })); + } + } +} + +#[derive(Debug)] +pub struct Proceed; + +impl IntoElement for Proceed { + fn into_element(&self) -> Element { + let mut namespace_declarations = HashSet::new(); + namespace_declarations.insert(NamespaceDeclaration { + prefix: None, + namespace: XMLNS.to_string(), + }); + Element { + name: Name { + namespace: Some(XMLNS.to_string()), + local_name: "proceed".to_string(), + }, + namespace_declarations, + attributes: HashMap::new(), + content: Vec::new(), + } + } +} + +impl FromElement for Proceed { + fn from_element(element: Element) -> peanuts::Result<Self> { + let Name { + namespace, + local_name, + } = element.name; + if namespace.as_deref() == Some(XMLNS) && &local_name == "proceed" { + return Ok(Proceed); + } else { + return Err(peanuts::Error::IncorrectName(Name { + namespace, + local_name, + })); + } + } +} + +pub struct Failure; + +impl IntoElement for Failure { + fn into_element(&self) -> Element { + let mut namespace_declarations = HashSet::new(); + namespace_declarations.insert(NamespaceDeclaration { + prefix: None, + namespace: XMLNS.to_string(), + }); + Element { + name: Name { + namespace: Some(XMLNS.to_string()), + local_name: "failure".to_string(), + }, + namespace_declarations, + attributes: HashMap::new(), + content: Vec::new(), + } + } +} + +impl FromElement for Failure { + fn from_element(element: Element) -> peanuts::Result<Self> { + let Name { + namespace, + local_name, + } = element.name; + if namespace.as_deref() == Some(XMLNS) && &local_name == "failure" { + return Ok(Failure); + } else { + return Err(peanuts::Error::IncorrectName(Name { + namespace, + local_name, + })); + } + } +} |