xmpp-parsers: Convert vCard-temp to xso

This also keeps all additional elements in the vCard, so they get
serialized back on the wire instead of being dropped.
This commit is contained in:
Emmanuel Gil Peyrot 2024-08-20 12:21:10 +02:00 • committed by xmpp ftw
commit 16b232523d
2 changed files with 28 additions and 30 deletions

View file

@ -28,6 +28,10 @@ XXXX-YY-ZZ RELEASER <admin@example.com>
- The bookmarks2 Conference `extensions` child is now an - The bookmarks2 Conference `extensions` child is now an
`Option<Extensions>` instead of a `Vec<Element>`, to distinguish `Option<Extensions>` instead of a `Vec<Element>`, to distinguish
between it being absent or empty (!472). between it being absent or empty (!472).
* Improvements:
- Keep unsupported vCard elements as `minidom::Element`, so that they
get serialized back instead of being dropped. We now also test for
the size of these elements (!472).
* New parsers/serialisers: * New parsers/serialisers:
- Stream Features (RFC 6120) (!400) - Stream Features (RFC 6120) (!400)
- Extensible SASL Profile (XEP-0388) - Extensible SASL Profile (XEP-0388)

View file

@ -14,7 +14,6 @@
//! see [`vcard_update`][crate::vcard_update] module. //! see [`vcard_update`][crate::vcard_update] module.
use xso::{ use xso::{
error::Error,
text::{Base64, StripWhitespace, TextCodec}, text::{Base64, StripWhitespace, TextCodec},
AsXml, FromXml, AsXml, FromXml,
}; };
@ -55,39 +54,16 @@ pub struct Binval {
} }
/// A `<vCard>` element; only the `<PHOTO>` element is supported for this legacy vCard ; the rest is ignored. /// A `<vCard>` element; only the `<PHOTO>` element is supported for this legacy vCard ; the rest is ignored.
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
#[xml(namespace = ns::VCARD, name = "vCard")]
pub struct VCard { pub struct VCard {
/// A photo element. /// A photo element.
#[xml(child(default))]
pub photo: Option<Photo>, pub photo: Option<Photo>,
}
impl TryFrom<Element> for VCard { /// Every other element in the vCard.
type Error = xso::error::Error; #[xml(element(n = ..))]
pub payloads: Vec<Element>,
fn try_from(value: Element) -> Result<Self, Self::Error> {
// Check that the root element is <vCard>
if !value.is("vCard", ns::VCARD) {
return Err(Error::Other(
"Root element is not <vCard xmlns='vcard-temp'>",
));
}
// Parse the <PHOTO> element, if any.
let photo = value
.get_child("PHOTO", ns::VCARD)
.map(|photo| Photo::try_from(photo.clone()))
.transpose()?;
// Return the result.
Ok(VCard { photo })
}
}
impl From<VCard> for Element {
fn from(vcard: VCard) -> Element {
Element::builder("vCard", ns::VCARD)
.append_all(vcard.photo)
.build()
}
} }
impl IqGetPayload for VCard {} impl IqGetPayload for VCard {}
@ -100,6 +76,24 @@ mod tests {
use base64::Engine; use base64::Engine;
use std::str::FromStr; use std::str::FromStr;
#[cfg(target_pointer_width = "32")]
#[test]
fn test_size() {
assert_size!(Photo, 24);
assert_size!(Type, 12);
assert_size!(Binval, 12);
assert_size!(VCard, 36);
}
#[cfg(target_pointer_width = "64")]
#[test]
fn test_size() {
assert_size!(Photo, 48);
assert_size!(Type, 24);
assert_size!(Binval, 24);
assert_size!(VCard, 72);
}
#[test] #[test]
fn test_vcard() { fn test_vcard() {
// Create some bytes: // Create some bytes: