xmpp-parsers: Remove Feature from disco#info

This was just a newtype for a String, but in general using it was harder
than without it.  This simplifies the public API.
This commit is contained in:
Link Mauve 2026-01-09 00:25:32 +01:00
commit 946d96d7c8
7 changed files with 23 additions and 40 deletions

View file

@ -12,6 +12,8 @@ XXXX-YY-ZZ RELEASER <admin@example.com>
used in XMPP.
- Remove the unnecessary SaslMechanisms struct, to directly extract
SASL mechanisms in a Vec<String> in StreamFeatures.
- The type of disco::DiscoInfoResult::features changed from
Vec<Feature> to Vec<String>, this lets us remove Feature as well.
- bind::BindFeature::required is now a bool, thanks to xsos flag.
- jingle_rtp::Description::rtcp_mux is now a bool flag too.
- stream_limits::Limits now extract directly to NonZeroU32.

View file

@ -7,7 +7,7 @@
use xso::{AsXml, FromXml};
use crate::data_forms::DataForm;
use crate::disco::{DiscoInfoQuery, DiscoInfoResult, Feature, Identity};
use crate::disco::{DiscoInfoQuery, DiscoInfoResult, Identity};
use crate::hashes::{Algo, Hash};
use crate::ns;
use crate::presence::PresencePayload;
@ -79,8 +79,8 @@ fn compute_items<T, F: Fn(&T) -> Vec<u8>>(things: &[T], encode: F) -> Vec<u8> {
string
}
fn compute_features(features: &[Feature]) -> Vec<u8> {
compute_items(features, |feature| compute_item(&feature.var))
fn compute_features(features: &[String]) -> Vec<u8> {
compute_items(features, |feature| compute_item(&feature))
}
fn compute_identities(identities: &[Identity]) -> Vec<u8> {

View file

@ -26,22 +26,6 @@ pub struct DiscoInfoQuery {
impl IqGetPayload for DiscoInfoQuery {}
/// Structure representing a `<feature xmlns='http://jabber.org/protocol/disco#info'/>` element.
#[derive(FromXml, AsXml, Debug, Clone, PartialEq, Eq, Hash)]
#[xml(namespace = ns::DISCO_INFO, name = "feature")]
pub struct Feature {
/// Namespace of the feature we want to represent.
#[xml(attribute)]
pub var: String,
}
impl Feature {
/// Create a new `<feature/>` with the according `@var`.
pub fn new<S: Into<String>>(var: S) -> Feature {
Feature { var: var.into() }
}
}
/// Structure representing an `<identity xmlns='http://jabber.org/protocol/disco#info'/>` element.
#[derive(FromXml, AsXml, Debug, Clone, PartialEq, Eq, Hash)]
#[xml(namespace = ns::DISCO_INFO, name = "identity")]
@ -113,8 +97,8 @@ pub struct DiscoInfoResult {
pub identities: Vec<Identity>,
/// List of features supported by this entity.
#[xml(child(n = ..))]
pub features: Vec<Feature>,
#[xml(extract(n = .., name = "feature", fields(attribute(name = "var", type_ = String))))]
pub features: Vec<String>,
/// List of extensions reported by this entity.
#[xml(child(n = ..))]
@ -192,7 +176,6 @@ mod tests {
#[test]
fn test_size() {
assert_size!(Identity, 48);
assert_size!(Feature, 12);
assert_size!(DiscoInfoQuery, 12);
assert_size!(DiscoInfoResult, 48);
@ -205,7 +188,6 @@ mod tests {
#[test]
fn test_size() {
assert_size!(Identity, 96);
assert_size!(Feature, 24);
assert_size!(DiscoInfoQuery, 24);
assert_size!(DiscoInfoResult, 96);
@ -325,9 +307,11 @@ mod tests {
FromElementError::Invalid(Error::Other(string)) => string,
_ => panic!(),
};
// TODO: Make xso generate a better error message, with s/unnamed field 0/'var'/ for
// instance.
assert_eq!(
message,
"Required attribute field 'var' on Feature element missing."
"Required attribute unnamed field 0 on extraction for field 'features' in DiscoInfoResult element missing."
);
}

View file

@ -7,7 +7,7 @@
use xso::{AsXml, FromXml};
use crate::data_forms::DataForm;
use crate::disco::{DiscoInfoQuery, DiscoInfoResult, Feature, Identity};
use crate::disco::{DiscoInfoQuery, DiscoInfoResult, Identity};
use crate::hashes::{Algo, Hash};
use crate::ns;
use crate::presence::PresencePayload;
@ -64,8 +64,8 @@ fn compute_items<'x, T: 'x, I: IntoIterator<Item = &'x T>, F: Fn(&'x T) -> Vec<u
string
}
fn compute_features(features: &[Feature]) -> Vec<u8> {
compute_items(features, 0x1c, |feature| compute_item(&feature.var))
fn compute_features(features: &[String]) -> Vec<u8> {
compute_items(features, 0x1c, |feature| compute_item(&feature))
}
fn compute_identities(identities: &[Identity]) -> Vec<u8> {