jingle_ft: Implement checksum parsers.

This commit is contained in:
Emmanuel Gil Peyrot 2017-10-31 16:41:22 +00:00
parent cf31506580
commit 667ae4c40f

View file

@ -219,6 +219,41 @@ pub struct Checksum {
pub file: File,
}
impl TryFrom<Element> for Checksum {
type Err = Error;
fn try_from(elem: Element) -> Result<Checksum, Error> {
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<Checksum> 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 = "<checksum xmlns='urn:xmpp:jingle:apps:file-transfer:5' name='coucou' creator='initiator'><file><hash xmlns='urn:xmpp:hashes:2' algo='sha-1'>w0mcJylzCn+AfvuGdqkty2+KP48=</hash></file></checksum>".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 = "<checksum xmlns='urn:xmpp:jingle:apps:file-transfer:5' name='coucou' creator='initiator'><coucou/></checksum>".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 = "<checksum xmlns='urn:xmpp:jingle:apps:file-transfer:5' name='coucou' creator='initiator' coucou=''><file><hash xmlns='urn:xmpp:hashes:2' algo='sha-1'>w0mcJylzCn+AfvuGdqkty2+KP48=</hash></file></checksum>".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 = "<checksum xmlns='urn:xmpp:jingle:apps:file-transfer:5' creator='initiator'><file><hash xmlns='urn:xmpp:hashes:2' algo='sha-1'>w0mcJylzCn+AfvuGdqkty2+KP48=</hash></file></checksum>".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 = "<checksum xmlns='urn:xmpp:jingle:apps:file-transfer:5' name='coucou' creator='coucou'><file><hash xmlns='urn:xmpp:hashes:2' algo='sha-1'>w0mcJylzCn+AfvuGdqkty2+KP48=</hash></file></checksum>".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.");
}
}