xmpp-parsers: Switch from zero-sized types to #[xml(flag)]

That way we can simply use true/false, instead of
Some(TheZeroSizedType)/None.
This commit is contained in:
Emmanuel Gil Peyrot 2025-01-25 19:39:49 +01:00
commit 244a9bbbf2
6 changed files with 19 additions and 40 deletions

View file

@ -42,6 +42,10 @@ XXXX-YY-ZZ RELEASER <admin@example.com>
- `Caps::hash` has been split into `Caps::hash` (the algo) and - `Caps::hash` has been split into `Caps::hash` (the algo) and
`Caps::ver` (the actual hash), to reflect the attributes (!517) `Caps::ver` (the actual hash), to reflect the attributes (!517)
- muc::MucUser now has an `invite` field - muc::MucUser now has an `invite` field
- cert_management::Append::no_cert_management,
cert_management::Item::no_cert_management,
ssm::StreamManagement::optional and starttls::StartTls::required are
now proper bools, instead of Option<ZeroSizedType> (!518)
* New parsers/serialisers: * New parsers/serialisers:
- Stream Features (RFC 6120) (!400) - Stream Features (RFC 6120) (!400)
- Spam Reporting (XEP-0377) (!506) - Spam Reporting (XEP-0377) (!506)

View file

@ -25,11 +25,6 @@ pub struct Cert {
pub data: Vec<u8>, pub data: Vec<u8>,
} }
/// Temporary zero-sized struct for when the no-cert-management element is present.
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
#[xml(namespace = ns::SASL_CERT, name = "no-cert-management")]
pub struct NoCertManagement;
/// For the client to upload an X.509 certificate. /// For the client to upload an X.509 certificate.
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)] #[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
#[xml(namespace = ns::SASL_CERT, name = "append")] #[xml(namespace = ns::SASL_CERT, name = "append")]
@ -43,9 +38,8 @@ pub struct Append {
pub cert: Cert, pub cert: Cert,
/// This client is forbidden from managing certificates. /// This client is forbidden from managing certificates.
// TODO: replace with `#[xml(flag)]` once we have it. #[xml(flag(name = "no-cert-management"))]
#[xml(child(default))] pub no_cert_management: bool,
pub no_cert_management: Option<NoCertManagement>,
} }
impl IqSetPayload for Append {} impl IqSetPayload for Append {}
@ -86,9 +80,8 @@ pub struct Item {
pub cert: Cert, pub cert: Cert,
/// This client is forbidden from managing certificates. /// This client is forbidden from managing certificates.
#[xml(child(default))] #[xml(flag(name = "no-cert-management"))]
// TODO: replace with `#[xml(flag)]` once we have it. pub no_cert_management: bool,
pub no_cert_management: Option<NoCertManagement>,
/// List of resources currently using this certificate. /// List of resources currently using this certificate.
#[xml(child(default))] #[xml(child(default))]
@ -138,7 +131,6 @@ mod tests {
#[cfg(target_pointer_width = "32")] #[cfg(target_pointer_width = "32")]
#[test] #[test]
fn test_size() { fn test_size() {
assert_size!(NoCertManagement, 0);
assert_size!(Append, 28); assert_size!(Append, 28);
assert_size!(Disable, 12); assert_size!(Disable, 12);
assert_size!(Revoke, 12); assert_size!(Revoke, 12);
@ -153,7 +145,6 @@ mod tests {
#[cfg(target_pointer_width = "64")] #[cfg(target_pointer_width = "64")]
#[test] #[test]
fn test_size() { fn test_size() {
assert_size!(NoCertManagement, 0);
assert_size!(Append, 56); assert_size!(Append, 56);
assert_size!(Disable, 24); assert_size!(Disable, 24);
assert_size!(Revoke, 24); assert_size!(Revoke, 24);
@ -225,7 +216,7 @@ mod tests {
cert: Cert { cert: Cert {
data: b"\0\0\0".to_vec(), data: b"\0\0\0".to_vec(),
}, },
no_cert_management: None, no_cert_management: false,
}; };
let elem: Element = append.into(); let elem: Element = append.into();
assert!(elem.is("append", ns::SASL_CERT)); assert!(elem.is("append", ns::SASL_CERT));
@ -251,7 +242,7 @@ mod tests {
cert: Cert { cert: Cert {
data: b"\0\0\0".to_vec(), data: b"\0\0\0".to_vec(),
}, },
no_cert_management: None, no_cert_management: false,
users: None, users: None,
}; };
@ -270,7 +261,7 @@ mod tests {
cert: Cert { cert: Cert {
data: b"\0\0\0".to_vec(), data: b"\0\0\0".to_vec(),
}, },
no_cert_management: None, no_cert_management: false,
}; };
let serialized: Element = append.into(); let serialized: Element = append.into();

View file

@ -269,7 +269,7 @@ mod tests {
let inline = auth.inline.unwrap(); let inline = auth.inline.unwrap();
assert_eq!(inline.bind2.unwrap().inline_features.len(), 0); assert_eq!(inline.bind2.unwrap().inline_features.len(), 0);
assert_eq!(inline.sm.unwrap(), StreamManagement { optional: None }); assert_eq!(inline.sm.unwrap(), StreamManagement { optional: false });
assert_eq!(inline.payloads.len(), 0); assert_eq!(inline.payloads.len(), 0);
} }

View file

@ -133,21 +133,14 @@ pub struct Resumed {
pub previd: StreamId, pub previd: StreamId,
} }
/// Marker whose presence indicates that negotiating stream management is
/// optional.
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
#[xml(namespace = ns::SM, name = "optional")]
pub struct Optional;
// TODO: add support for optional and required. // TODO: add support for optional and required.
/// Represents availability of Stream Management in `<stream:features/>`. /// Represents availability of Stream Management in `<stream:features/>`.
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)] #[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
#[xml(namespace = ns::SM, name = "sm")] #[xml(namespace = ns::SM, name = "sm")]
pub struct StreamManagement { pub struct StreamManagement {
// TODO: replace with #[xml(flag)] once we have it.
/// `<optional/>` flag. /// `<optional/>` flag.
#[xml(child(default))] #[xml(flag(name = "optional"))]
pub optional: Option<Optional>, pub optional: bool,
} }
/// Application-specific error condition to use when the peer acknowledges /// Application-specific error condition to use when the peer acknowledges
@ -230,7 +223,6 @@ mod tests {
assert_size!(Resume, 16); assert_size!(Resume, 16);
assert_size!(Resumed, 16); assert_size!(Resumed, 16);
assert_size!(StreamManagement, 1); assert_size!(StreamManagement, 1);
assert_size!(Optional, 0);
assert_size!(HandledCountTooHigh, 8); assert_size!(HandledCountTooHigh, 8);
} }
@ -246,7 +238,6 @@ mod tests {
assert_size!(Resume, 32); assert_size!(Resume, 32);
assert_size!(Resumed, 32); assert_size!(Resumed, 32);
assert_size!(StreamManagement, 1); assert_size!(StreamManagement, 1);
assert_size!(Optional, 0);
assert_size!(HandledCountTooHigh, 8); assert_size!(HandledCountTooHigh, 8);
} }

View file

@ -25,16 +25,10 @@ pub struct Proceed;
#[xml(namespace = ns::TLS, name = "starttls")] #[xml(namespace = ns::TLS, name = "starttls")]
pub struct StartTls { pub struct StartTls {
/// Marker for mandatory StartTLS. /// Marker for mandatory StartTLS.
// TODO: replace with `#[xml(flag)]` once we have it #[xml(flag(name = "required"))]
#[xml(child(default))] pub required: bool,
pub required: Option<RequiredStartTls>,
} }
/// Marker for mandatory StartTLS.
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
#[xml(namespace = ns::TLS, name = "required")]
pub struct RequiredStartTls;
/// Enum which allows parsing/serialising any STARTTLS element. /// Enum which allows parsing/serialising any STARTTLS element.
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)] #[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
#[xml()] #[xml()]
@ -58,7 +52,6 @@ mod tests {
assert_size!(Request, 0); assert_size!(Request, 0);
assert_size!(Proceed, 0); assert_size!(Proceed, 0);
assert_size!(StartTls, 1); assert_size!(StartTls, 1);
assert_size!(RequiredStartTls, 0);
assert_size!(Nonza, 1); assert_size!(Nonza, 1);
} }
@ -82,7 +75,7 @@ mod tests {
.parse() .parse()
.unwrap(); .unwrap();
let starttls = StartTls::try_from(elem.clone()).unwrap(); let starttls = StartTls::try_from(elem.clone()).unwrap();
assert_eq!(starttls.required, None); assert_eq!(starttls.required, false);
let elem2 = Element::from(starttls); let elem2 = Element::from(starttls);
assert_eq!(elem, elem2); assert_eq!(elem, elem2);
@ -91,7 +84,7 @@ mod tests {
.parse() .parse()
.unwrap(); .unwrap();
let starttls = StartTls::try_from(elem.clone()).unwrap(); let starttls = StartTls::try_from(elem.clone()).unwrap();
assert_eq!(starttls.required, Some(RequiredStartTls)); assert_eq!(starttls.required, true);
let elem2 = Element::from(starttls); let elem2 = Element::from(starttls);
assert_eq!(elem, elem2); assert_eq!(elem, elem2);

View file

@ -129,7 +129,7 @@ mod tests {
assert_eq!(features.can_bind(), false); assert_eq!(features.can_bind(), false);
assert_eq!(features.sasl_mechanisms.mechanisms.len(), 0); assert_eq!(features.sasl_mechanisms.mechanisms.len(), 0);
assert_eq!(features.can_starttls(), true); assert_eq!(features.can_starttls(), true);
assert_eq!(features.starttls.unwrap().required.is_some(), true); assert_eq!(features.starttls.unwrap().required, true);
} }
#[test] #[test]