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
`Option<Extensions>` instead of a `Vec<Element>`, to distinguish
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:
- Stream Features (RFC 6120) (!400)
- Extensible SASL Profile (XEP-0388)

View file

@ -14,7 +14,6 @@
//! see [`vcard_update`][crate::vcard_update] module.
use xso::{
error::Error,
text::{Base64, StripWhitespace, TextCodec},
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.
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
#[xml(namespace = ns::VCARD, name = "vCard")]
pub struct VCard {
/// A photo element.
#[xml(child(default))]
pub photo: Option<Photo>,
}
impl TryFrom<Element> for VCard {
type Error = xso::error::Error;
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()
}
/// Every other element in the vCard.
#[xml(element(n = ..))]
pub payloads: Vec<Element>,
}
impl IqGetPayload for VCard {}
@ -100,6 +76,24 @@ mod tests {
use base64::Engine;
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]
fn test_vcard() {
// Create some bytes: