From 667ae4c40f52f798a3b7c7a8d3ea60a0e7d78cb1 Mon Sep 17 00:00:00 2001 From: Emmanuel Gil Peyrot Date: Tue, 31 Oct 2017 16:41:22 +0000 Subject: [PATCH] jingle_ft: Implement checksum parsers. --- src/jingle_ft.rs | 82 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/src/jingle_ft.rs b/src/jingle_ft.rs index 5cc739c8..3ee4e4a9 100644 --- a/src/jingle_ft.rs +++ b/src/jingle_ft.rs @@ -219,6 +219,41 @@ pub struct Checksum { pub file: File, } +impl TryFrom for Checksum { + type Err = Error; + + fn try_from(elem: Element) -> Result { + check_self!(elem, "checksum", ns::JINGLE_FT); + check_no_unknown_attributes!(elem, "checksum", ["name", "creator"]); + let mut file = None; + for child in elem.children() { + if file.is_some() { + return Err(Error::ParseError("JingleFT checksum element must have exactly one child.")); + } + file = Some(File::try_from(child.clone())?); + } + if file.is_none() { + return Err(Error::ParseError("JingleFT checksum element must have exactly one child.")); + } + Ok(Checksum { + name: get_attr!(elem, "name", required), + creator: get_attr!(elem, "creator", required), + file: file.unwrap(), + }) + } +} + +impl From for Element { + fn from(checksum: Checksum) -> Element { + Element::builder("checksum") + .ns(ns::JINGLE_FT) + .attr("name", checksum.name) + .attr("creator", checksum.creator) + .append(checksum.file) + .build() + } +} + #[derive(Debug, Clone)] pub struct Received { pub name: ContentId, @@ -381,4 +416,51 @@ mod tests { }; assert_eq!(message, "Unknown value for 'creator' attribute."); } + + #[test] + fn test_checksum() { + let elem: Element = "w0mcJylzCn+AfvuGdqkty2+KP48=".parse().unwrap(); + let hash = vec!(195, 73, 156, 39, 41, 115, 10, 127, 128, 126, 251, 134, 118, 169, 45, 203, 111, 138, 63, 143); + let checksum = Checksum::try_from(elem).unwrap(); + assert_eq!(checksum.name, ContentId(String::from("coucou"))); + assert_eq!(checksum.creator, Creator::Initiator); + assert_eq!(checksum.file.hashes, vec!(Hash { algo: Algo::Sha_1, hash: hash.clone() })); + let elem2 = Element::from(checksum); + let checksum2 = Checksum::try_from(elem2).unwrap(); + assert_eq!(checksum2.name, ContentId(String::from("coucou"))); + assert_eq!(checksum2.creator, Creator::Initiator); + assert_eq!(checksum2.file.hashes, vec!(Hash { algo: Algo::Sha_1, hash: hash.clone() })); + + let elem: Element = "".parse().unwrap(); + let error = Checksum::try_from(elem).unwrap_err(); + let message = match error { + Error::ParseError(string) => string, + _ => panic!(), + }; + assert_eq!(message, "This is not a file element."); + + let elem: Element = "w0mcJylzCn+AfvuGdqkty2+KP48=".parse().unwrap(); + let error = Checksum::try_from(elem).unwrap_err(); + let message = match error { + Error::ParseError(string) => string, + _ => panic!(), + }; + assert_eq!(message, "Unknown attribute in checksum element."); + + let elem: Element = "w0mcJylzCn+AfvuGdqkty2+KP48=".parse().unwrap(); + let error = Checksum::try_from(elem).unwrap_err(); + let message = match error { + Error::ParseError(string) => string, + _ => panic!(), + }; + assert_eq!(message, "Required attribute 'name' missing."); + + let elem: Element = "w0mcJylzCn+AfvuGdqkty2+KP48=".parse().unwrap(); + let error = Checksum::try_from(elem).unwrap_err(); + let message = match error { + Error::ParseError(string) => string, + _ => panic!(), + }; + assert_eq!(message, "Unknown value for 'creator' attribute."); + } }