use error::Error;
use fromxml::FromXml;
use quick_xml::{Element, Event, XmlReader, XmlWriter};
use quick_xml::error::Error as XmlError;
use std::str::FromStr;
use toxml::ToXml;
use url::Url;
#[derive(Debug, Default, Clone, PartialEq)]
pub struct Cloud {
domain: String,
port: String,
path: String,
register_procedure: String,
protocol: String,
}
impl Cloud {
pub fn domain(&self) -> &str {
self.domain.as_str()
}
pub fn port(&self) -> &str {
self.port.as_str()
}
pub fn path(&self) -> &str {
self.path.as_str()
}
pub fn register_procedure(&self) -> &str {
self.register_procedure.as_str()
}
pub fn protocol(&self) -> &str {
self.protocol.as_str()
}
}
impl FromXml for Cloud {
fn from_xml<R: ::std::io::BufRead>(mut reader: XmlReader<R>,
element: Element)
-> Result<(Self, XmlReader<R>), Error> {
let mut domain = None;
let mut port = None;
let mut path = None;
let mut register_procedure = None;
let mut protocol = None;
for attr in element.attributes().with_checks(false).unescaped() {
if let Ok(attr) = attr {
match attr.0 {
b"domain" if domain.is_none() => {
domain = Some(String::from_utf8(attr.1.into_owned())?);
}
b"port" if port.is_none() => {
port = Some(String::from_utf8(attr.1.into_owned())?);
}
b"path" if path.is_none() => {
path = Some(String::from_utf8(attr.1.into_owned())?);
}
b"registerProcedure" if register_procedure.is_none() => {
register_procedure = Some(String::from_utf8(attr.1.into_owned())?);
}
b"protocol" if protocol.is_none() => {
protocol = Some(String::from_utf8(attr.1.into_owned())?);
}
_ => {}
}
}
}
skip_element!(reader);
let domain = domain.unwrap_or_default();
let port = port.unwrap_or_default();
let path = path.unwrap_or_default();
let register_procedure = register_procedure.unwrap_or_default();
let protocol = protocol.unwrap_or_default();
Ok((Cloud {
domain: domain,
port: port,
path: path,
register_procedure: register_procedure,
protocol: protocol,
},
reader))
}
}
impl ToXml for Cloud {
fn to_xml<W: ::std::io::Write>(&self, writer: &mut XmlWriter<W>) -> Result<(), XmlError> {
let element = Element::new(b"cloud");
writer
.write(Event::Start({
let mut element = element.clone();
let attrs = &[(b"domain" as &[u8], &self.domain),
(b"port", &self.port),
(b"path", &self.path),
(b"registerProcedure", &self.register_procedure),
(b"protocol", &self.protocol)];
element.extend_attributes(attrs.into_iter().map(|v| *v));
element
}))?;
writer.write(Event::End(element))
}
}
#[derive(Debug, Clone, Default)]
pub struct CloudBuilder {
domain: String,
port: i64,
path: String,
register_procedure: String,
protocol: String,
}
impl CloudBuilder {
pub fn new() -> CloudBuilder {
CloudBuilder::default()
}
pub fn domain(mut self, domain: &str) -> CloudBuilder {
self.domain = domain.to_string();
self
}
pub fn port(mut self, port: i64) -> CloudBuilder {
self.port = port;
self
}
pub fn path(mut self, path: &str) -> CloudBuilder {
self.path = path.to_string();
self
}
pub fn register_procedure(mut self, register_procedure: &str) -> CloudBuilder {
self.register_procedure = register_procedure.to_string();
self
}
pub fn protocol(mut self, protocol: &str) -> CloudBuilder {
self.protocol = protocol.to_string();
self
}
pub fn validate(self) -> Result<CloudBuilder, Error> {
if self.port < 0 {
return Err(Error::Validation("Cloud Port cannot be a negative value".to_string()));
}
Url::parse(self.domain.as_str())?;
match CloudProtocol::from_str(self.protocol.as_str()) {
Ok(_) => (),
Err(err) => return Err(Error::Validation(err.to_string())),
};
Ok(self)
}
pub fn finalize(self) -> Result<Cloud, Error> {
let port = self.port.to_string();
Ok(Cloud {
domain: self.domain,
port: port,
path: self.path,
register_procedure: self.register_procedure,
protocol: self.protocol,
})
}
}
#[derive(Clone, Debug)]
enum CloudProtocol {
HttpPost,
XmlRpc,
Soap,
}
impl FromStr for CloudProtocol {
type Err = &'static str;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"http-post" => Ok(CloudProtocol::HttpPost),
"xml-rpc" => Ok(CloudProtocol::XmlRpc),
"soap" => Ok(CloudProtocol::Soap),
_ => Err("not a valid value"),
}
}
}