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,
}));
}
}
}