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

Emmanuel Gil Peyrot created

That way we can simply use true/false, instead of
Some(TheZeroSizedType)/None.

Change summary

parsers/ChangeLog              |  4 ++++
parsers/src/cert_management.rs | 23 +++++++----------------
parsers/src/sasl2.rs           |  2 +-
parsers/src/sm.rs              | 13 ++-----------
parsers/src/starttls.rs        | 15 ++++-----------
parsers/src/stream_features.rs |  2 +-
6 files changed, 19 insertions(+), 40 deletions(-)

Detailed changes

parsers/ChangeLog 🔗

@@ -42,6 +42,10 @@ XXXX-YY-ZZ RELEASER <admin@example.com>
       - `Caps::hash` has been split into `Caps::hash` (the algo) and
         `Caps::ver` (the actual hash), to reflect the attributes (!517)
       - 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:
       - Stream Features (RFC 6120) (!400)
       - Spam Reporting (XEP-0377) (!506)

parsers/src/cert_management.rs 🔗

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

parsers/src/sasl2.rs 🔗

@@ -269,7 +269,7 @@ mod tests {
 
         let inline = auth.inline.unwrap();
         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);
     }
 

parsers/src/sm.rs 🔗

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

parsers/src/starttls.rs 🔗

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

parsers/src/stream_features.rs 🔗

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