use error::Error;
use fromxml::FromXml;
use quick_xml::{Element, Event, XmlReader, XmlWriter};
use quick_xml::error::Error as XmlError;
use toxml::ToXml;
use url::Url;
#[derive(Debug, Default, Clone, PartialEq)]
pub struct Category {
name: String,
domain: Option<String>,
}
impl Category {
pub fn name(&self) -> &str {
self.name.as_str()
}
pub fn domain(&self) -> Option<&str> {
self.domain.as_ref().map(|s| s.as_str())
}
}
impl FromXml for Category {
fn from_xml<R: ::std::io::BufRead>(mut reader: XmlReader<R>,
element: Element)
-> Result<(Self, XmlReader<R>), Error> {
let mut domain = None;
for attr in element.attributes().with_checks(false).unescaped() {
if let Ok(attr) = attr {
if attr.0 == b"domain" {
domain = Some(String::from_utf8(attr.1.into_owned())?);
break;
}
}
}
let content = element_text!(reader).unwrap_or_default();
Ok((Category {
name: content,
domain: domain,
},
reader))
}
}
impl ToXml for Category {
fn to_xml<W: ::std::io::Write>(&self, writer: &mut XmlWriter<W>) -> Result<(), XmlError> {
let element = Element::new(b"category");
writer
.write(Event::Start({
let mut element = element.clone();
if let Some(ref domain) = self.domain {
element.extend_attributes(::std::iter::once((b"domain",
domain)));
}
element
}))?;
writer.write(Event::Text(Element::new(self.name.as_str())))?;
writer.write(Event::End(element))
}
}
#[derive(Debug, Clone, Default)]
pub struct CategoryBuilder {
name: String,
domain: Option<String>,
}
impl CategoryBuilder {
pub fn new() -> CategoryBuilder {
CategoryBuilder::default()
}
pub fn name(mut self, name: &str) -> CategoryBuilder {
self.name = name.to_string();
self
}
pub fn domain(mut self, domain: Option<String>) -> CategoryBuilder {
self.domain = domain;
self
}
pub fn validate(self) -> Result<CategoryBuilder, Error> {
if let Some(ref domain) = self.domain {
Url::parse(domain)?;
}
Ok(self)
}
pub fn finalize(self) -> Result<Category, Error> {
Ok(Category {
name: self.name,
domain: self.domain,
})
}
}