Make TryFrom<Element> chainable
This allows constructs like:
```rust
let residual = match Iq::try_from(stanza) {
Ok(iq) => return handle_iq(..),
Err(Error::TypeMismatch(_, _, v)) => v,
Err(other) => return handle_parse_error(..),
};
let residual = match Message::try_from(stanza) {
..
};
let residual = ..
log::warn!("unhandled object: {:?}", residual);
```
The interesting part of this is that this could be used in a loop over a
Vec<Box<dyn FnMut(Element) -> ControlFlow<SomeResult, Element>>, i.e. in
a parsing loop for a generic XML/XMPP stream.
The advantage is that the stanza.is() check runs only once (in
check_self!) and doesn't need to be duplicated outside, and it reduces
the use of magic strings.
This commit is contained in:
parent
3b3a4ff0c8
commit
2f7d5edb8a
8 changed files with 68 additions and 25 deletions
|
|
@ -289,7 +289,7 @@ impl TryFrom<Element> for Checksum {
|
|||
"JingleFT checksum element must have exactly one child.",
|
||||
));
|
||||
}
|
||||
file = Some(File::try_from(child.clone())?);
|
||||
file = Some(File::try_from(child.clone()).map_err(|e| e.hide_type_mismatch())?);
|
||||
}
|
||||
if file.is_none() {
|
||||
return Err(Error::ParseError(
|
||||
|
|
@ -541,9 +541,9 @@ mod tests {
|
|||
let error = Checksum::try_from(elem).unwrap_err();
|
||||
let message = match error {
|
||||
Error::ParseError(string) => string,
|
||||
_ => panic!(),
|
||||
other => panic!("unexpected error: {:?}", other),
|
||||
};
|
||||
assert_eq!(message, "This is not a file element.");
|
||||
assert_eq!(message, "Unexpected child 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();
|
||||
|
|
|
|||
Loading…
Reference in a new issue