// Copyright (c) 2017 Emmanuel Gil Peyrot // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. use try_from::TryFrom; use jid::Jid; use minidom::Element; use error::Error; use ns; generate_empty_element!(BlocklistRequest, "blocklist", ns::BLOCKING); fn get_children_items(elem: Element) -> Result, Error> { let mut items = vec!(); for child in elem.children() { check_self!(child, "item", ns::BLOCKING); check_no_unknown_attributes!(child, "item", ["jid"]); check_no_children!(child, "item"); items.push(get_attr!(child, "jid", required)); } Ok(items) } macro_rules! generate_blocking_element { ($elem:ident, $name:tt) => ( #[derive(Debug, Clone)] pub struct $elem { pub items: Vec, } impl TryFrom for $elem { type Err = Error; fn try_from(elem: Element) -> Result<$elem, Error> { check_self!(elem, $name, ns::BLOCKING); check_no_attributes!(elem, $name); Ok($elem { items: get_children_items(elem)?, }) } } impl From<$elem> for Element { fn from(elem: $elem) -> Element { Element::builder($name) .ns(ns::BLOCKING) .append(elem.items.into_iter().map(|jid| { Element::builder("item") .ns(ns::BLOCKING) .attr("jid", jid) .build() }).collect::>()) .build() } } ); } generate_blocking_element!(BlocklistResult, "blocklist"); generate_blocking_element!(Block, "block"); generate_blocking_element!(Unblock, "unblock"); generate_empty_element!(Blocked, "blocked", ns::BLOCKING_ERRORS); #[cfg(test)] mod tests { use super::*; #[test] fn test_simple() { let elem: Element = "".parse().unwrap(); let request_elem = elem.clone(); BlocklistRequest::try_from(request_elem).unwrap(); let result_elem = elem.clone(); let result = BlocklistResult::try_from(result_elem).unwrap(); assert_eq!(result.items, vec!()); let elem: Element = "".parse().unwrap(); let block = Block::try_from(elem).unwrap(); assert_eq!(block.items, vec!()); let elem: Element = "".parse().unwrap(); let unblock = Unblock::try_from(elem).unwrap(); assert_eq!(unblock.items, vec!()); } #[test] fn test_items() { let elem: Element = "".parse().unwrap(); let two_items = vec!( Jid { node: Some(String::from("coucou")), domain: String::from("coucou"), resource: None, }, Jid { node: None, domain: String::from("domain"), resource: None, }, ); let request_elem = elem.clone(); let error = BlocklistRequest::try_from(request_elem).unwrap_err(); let message = match error { Error::ParseError(string) => string, _ => panic!(), }; assert_eq!(message, "Unknown child in blocklist element."); let result_elem = elem.clone(); let result = BlocklistResult::try_from(result_elem).unwrap(); assert_eq!(result.items, two_items); let elem: Element = "".parse().unwrap(); let block = Block::try_from(elem).unwrap(); assert_eq!(block.items, two_items); let elem: Element = "".parse().unwrap(); let unblock = Unblock::try_from(elem).unwrap(); assert_eq!(unblock.items, two_items); } #[test] fn test_invalid() { let elem: Element = "".parse().unwrap(); let request_elem = elem.clone(); let error = BlocklistRequest::try_from(request_elem).unwrap_err(); let message = match error { Error::ParseError(string) => string, _ => panic!(), }; assert_eq!(message, "Unknown attribute in blocklist element."); let result_elem = elem.clone(); let error = BlocklistResult::try_from(result_elem).unwrap_err(); let message = match error { Error::ParseError(string) => string, _ => panic!(), }; assert_eq!(message, "Unknown attribute in blocklist element."); let elem: Element = "".parse().unwrap(); let error = Block::try_from(elem).unwrap_err(); let message = match error { Error::ParseError(string) => string, _ => panic!(), }; assert_eq!(message, "Unknown attribute in block element."); let elem: Element = "".parse().unwrap(); let error = Unblock::try_from(elem).unwrap_err(); let message = match error { Error::ParseError(string) => string, _ => panic!(), }; assert_eq!(message, "Unknown attribute in unblock element."); } }