diff --git a/parsers/ChangeLog b/parsers/ChangeLog index 2f621a29768b16b4d8dfc8e66b8aa20252e07e17..b8721e58a30261ff4adbfc479b05c00cf3618d67 100644 --- a/parsers/ChangeLog +++ b/parsers/ChangeLog @@ -32,6 +32,7 @@ XXXX-YY-ZZ RELEASER - RFC 6120 stream errors * Improvements: - Add support for ` in XEP-0198 feature advertisment + - Add support application-specific error conditions in XEP-0198 Version 0.21.0: 2024-07-25 Emmanuel Gil Peyrot diff --git a/parsers/src/sm.rs b/parsers/src/sm.rs index 97f94cf7961b1fb17ddf0464fc46195a1cd287a6..c9fcdf137be58439d44204434cfc0742483b94d3 100644 --- a/parsers/src/sm.rs +++ b/parsers/src/sm.rs @@ -157,6 +157,36 @@ pub struct StreamManagement { pub optional: Option, } +/// Application-specific error condition to use when the peer acknowledges +/// more stanzas than the local side has sent. +#[derive(FromXml, AsXml, PartialEq, Debug, Clone)] +#[xml(namespace = ns::SM, name = "handled-count-too-high")] +pub struct HandledCountTooHigh { + /// The `h` value received by the peer. + #[xml(attribute)] + pub h: u32, + + /// The number of stanzas which were in fact sent. + #[xml(attribute = "send-count")] + pub send_count: u32, +} + +impl From for crate::stream_error::StreamError { + fn from(other: HandledCountTooHigh) -> Self { + Self { + condition: crate::stream_error::DefinedCondition::UndefinedCondition, + text: Some(( + None, + format!( + "You acknowledged {} stanza(s), while I only sent {} so far.", + other.h, other.send_count + ), + )), + application_specific: vec![other.into()], + } + } +} + #[cfg(test)] mod tests { use super::*; @@ -176,6 +206,7 @@ mod tests { assert_size!(Resumed, 16); assert_size!(StreamManagement, 1); assert_size!(Optional, 0); + assert_size!(HandledCountTooHigh, 8); } #[cfg(target_pointer_width = "64")] @@ -192,6 +223,7 @@ mod tests { assert_size!(Resumed, 32); assert_size!(StreamManagement, 1); assert_size!(Optional, 0); + assert_size!(HandledCountTooHigh, 8); } #[test] @@ -207,6 +239,16 @@ mod tests { StreamManagement::try_from(elem).unwrap(); } + #[test] + fn handle_count_too_high() { + let elem: Element = "" + .parse() + .unwrap(); + let elem = HandledCountTooHigh::try_from(elem).unwrap(); + assert_eq!(elem.h, 10); + assert_eq!(elem.send_count, 8); + } + #[test] fn resume() { let elem: Element = ""