mirror of
https://gitlab.com/xmpp-rs/xmpp-rs.git
synced 2024-07-12 22:21:53 +00:00
Support desc element in field
From [XEP-0004: Data Forms](https://xmpp.org/extensions/xep-0004.html#protocol-field): > ... > The <field/> element MAY contain any of the following child elements: > > <desc/> > The XML character data of this element provides a natural-language > description of the field, intended for presentation in a > user-agent (e.g., as a "tool-tip", help button, or explanatory text > provided near the field). The <desc/> element SHOULD NOT contain > newlines (the \n and \r characters), since layout is the > responsibility of a user agent, and any handling of > newlines (e.g., presentation in a user interface) is unspecified > herein. (Note: To provide a description of a field, it > is RECOMMENDED to use a <desc/> element rather than > a separate <field/> element of type "fixed".) > ...
This commit is contained in:
parent
cb3da52ba2
commit
a1bee56ee1
4 changed files with 46 additions and 2 deletions
|
@ -82,6 +82,9 @@ pub struct Field {
|
||||||
/// The form will be rejected if this field isn’t present.
|
/// The form will be rejected if this field isn’t present.
|
||||||
pub required: bool,
|
pub required: bool,
|
||||||
|
|
||||||
|
/// The natural-language description of the field, intended for presentation in a user-agent
|
||||||
|
pub desc: Option<String>,
|
||||||
|
|
||||||
/// A list of allowed values.
|
/// A list of allowed values.
|
||||||
pub options: Vec<Option_>,
|
pub options: Vec<Option_>,
|
||||||
|
|
||||||
|
@ -100,6 +103,7 @@ impl Field {
|
||||||
type_,
|
type_,
|
||||||
label: None,
|
label: None,
|
||||||
required: false,
|
required: false,
|
||||||
|
desc: None,
|
||||||
options: Vec::new(),
|
options: Vec::new(),
|
||||||
media: Vec::new(),
|
media: Vec::new(),
|
||||||
values: Vec::new(),
|
values: Vec::new(),
|
||||||
|
@ -174,6 +178,7 @@ impl TryFrom<Element> for Field {
|
||||||
type_: get_attr!(elem, "type", Default),
|
type_: get_attr!(elem, "type", Default),
|
||||||
label: get_attr!(elem, "label", Option),
|
label: get_attr!(elem, "label", Option),
|
||||||
required: false,
|
required: false,
|
||||||
|
desc: None,
|
||||||
options: vec![],
|
options: vec![],
|
||||||
values: vec![],
|
values: vec![],
|
||||||
media: vec![],
|
media: vec![],
|
||||||
|
@ -204,6 +209,10 @@ impl TryFrom<Element> for Field {
|
||||||
} else if element.is("media", ns::MEDIA_ELEMENT) {
|
} else if element.is("media", ns::MEDIA_ELEMENT) {
|
||||||
let media_element = MediaElement::try_from(element.clone())?;
|
let media_element = MediaElement::try_from(element.clone())?;
|
||||||
field.media.push(media_element);
|
field.media.push(media_element);
|
||||||
|
} else if element.is("desc", ns::DATA_FORMS) {
|
||||||
|
check_no_children!(element, "value");
|
||||||
|
check_no_attributes!(element, "value");
|
||||||
|
field.desc = Some(element.text());
|
||||||
} else {
|
} else {
|
||||||
return Err(Error::ParseError(
|
return Err(Error::ParseError(
|
||||||
"Field child isn’t a value, option or media element.",
|
"Field child isn’t a value, option or media element.",
|
||||||
|
@ -374,7 +383,7 @@ mod tests {
|
||||||
fn test_size() {
|
fn test_size() {
|
||||||
assert_size!(Option_, 24);
|
assert_size!(Option_, 24);
|
||||||
assert_size!(FieldType, 1);
|
assert_size!(FieldType, 1);
|
||||||
assert_size!(Field, 64);
|
assert_size!(Field, 76);
|
||||||
assert_size!(DataFormType, 1);
|
assert_size!(DataFormType, 1);
|
||||||
assert_size!(DataForm, 52);
|
assert_size!(DataForm, 52);
|
||||||
}
|
}
|
||||||
|
@ -384,7 +393,7 @@ mod tests {
|
||||||
fn test_size() {
|
fn test_size() {
|
||||||
assert_size!(Option_, 48);
|
assert_size!(Option_, 48);
|
||||||
assert_size!(FieldType, 1);
|
assert_size!(FieldType, 1);
|
||||||
assert_size!(Field, 128);
|
assert_size!(Field, 152);
|
||||||
assert_size!(DataFormType, 1);
|
assert_size!(DataFormType, 1);
|
||||||
assert_size!(DataForm, 104);
|
assert_size!(DataForm, 104);
|
||||||
}
|
}
|
||||||
|
@ -428,6 +437,7 @@ mod tests {
|
||||||
type_: FieldType::Fixed,
|
type_: FieldType::Fixed,
|
||||||
label: None,
|
label: None,
|
||||||
required: false,
|
required: false,
|
||||||
|
desc: None,
|
||||||
options: vec![],
|
options: vec![],
|
||||||
values: vec!["Section 1: Bot Info".to_string()],
|
values: vec!["Section 1: Bot Info".to_string()],
|
||||||
media: vec![],
|
media: vec![],
|
||||||
|
@ -435,6 +445,30 @@ mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_desc() {
|
||||||
|
let elem: Element =
|
||||||
|
"<x xmlns='jabber:x:data' type='form'><field type='jid-multi' label='People to invite' var='invitelist'><desc>Tell all your friends about your new bot!</desc></field></x>"
|
||||||
|
.parse()
|
||||||
|
.unwrap();
|
||||||
|
let form = DataForm::try_from(elem).unwrap();
|
||||||
|
assert_eq!(form.type_, DataFormType::Form);
|
||||||
|
assert!(form.form_type.is_none());
|
||||||
|
assert_eq!(
|
||||||
|
form.fields,
|
||||||
|
vec![Field {
|
||||||
|
var: Some("invitelist".to_string()),
|
||||||
|
type_: FieldType::JidMulti,
|
||||||
|
label: Some("People to invite".to_string()),
|
||||||
|
required: false,
|
||||||
|
desc: Some("Tell all your friends about your new bot!".to_string()),
|
||||||
|
options: vec![],
|
||||||
|
values: vec![],
|
||||||
|
media: vec![],
|
||||||
|
}]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_invalid() {
|
fn test_invalid() {
|
||||||
let elem: Element = "<x xmlns='jabber:x:data'/>".parse().unwrap();
|
let elem: Element = "<x xmlns='jabber:x:data'/>".parse().unwrap();
|
||||||
|
|
|
@ -233,6 +233,7 @@ mod tests {
|
||||||
type_: FieldType::ListSingle,
|
type_: FieldType::ListSingle,
|
||||||
label: None,
|
label: None,
|
||||||
required: false,
|
required: false,
|
||||||
|
desc: None,
|
||||||
options: vec![],
|
options: vec![],
|
||||||
values: vec![String::from("whitelist")],
|
values: vec![String::from("whitelist")],
|
||||||
media: vec![],
|
media: vec![],
|
||||||
|
@ -280,6 +281,7 @@ mod tests {
|
||||||
type_: FieldType::ListSingle,
|
type_: FieldType::ListSingle,
|
||||||
label: None,
|
label: None,
|
||||||
required: false,
|
required: false,
|
||||||
|
desc: None,
|
||||||
options: vec![],
|
options: vec![],
|
||||||
values: vec![String::from("whitelist")],
|
values: vec![String::from("whitelist")],
|
||||||
media: vec![],
|
media: vec![],
|
||||||
|
|
|
@ -625,6 +625,7 @@ mod tests {
|
||||||
type_: FieldType::ListSingle,
|
type_: FieldType::ListSingle,
|
||||||
label: None,
|
label: None,
|
||||||
required: false,
|
required: false,
|
||||||
|
desc: None,
|
||||||
options: vec![],
|
options: vec![],
|
||||||
values: vec![String::from("whitelist")],
|
values: vec![String::from("whitelist")],
|
||||||
media: vec![],
|
media: vec![],
|
||||||
|
|
|
@ -91,6 +91,7 @@ pub fn generate_address_field<S: Into<String>>(var: S, values: Vec<String>) -> F
|
||||||
type_: FieldType::ListMulti,
|
type_: FieldType::ListMulti,
|
||||||
label: None,
|
label: None,
|
||||||
required: false,
|
required: false,
|
||||||
|
desc: None,
|
||||||
options: vec![],
|
options: vec![],
|
||||||
values,
|
values,
|
||||||
media: vec![],
|
media: vec![],
|
||||||
|
@ -126,6 +127,7 @@ mod tests {
|
||||||
type_: FieldType::ListMulti,
|
type_: FieldType::ListMulti,
|
||||||
label: None,
|
label: None,
|
||||||
required: false,
|
required: false,
|
||||||
|
desc: None,
|
||||||
options: vec![],
|
options: vec![],
|
||||||
values: vec![],
|
values: vec![],
|
||||||
media: vec![],
|
media: vec![],
|
||||||
|
@ -135,6 +137,7 @@ mod tests {
|
||||||
type_: FieldType::ListMulti,
|
type_: FieldType::ListMulti,
|
||||||
label: None,
|
label: None,
|
||||||
required: false,
|
required: false,
|
||||||
|
desc: None,
|
||||||
options: vec![],
|
options: vec![],
|
||||||
values: vec![
|
values: vec![
|
||||||
String::from("xmpp:admin@foo.bar"),
|
String::from("xmpp:admin@foo.bar"),
|
||||||
|
@ -148,6 +151,7 @@ mod tests {
|
||||||
type_: FieldType::ListMulti,
|
type_: FieldType::ListMulti,
|
||||||
label: None,
|
label: None,
|
||||||
required: false,
|
required: false,
|
||||||
|
desc: None,
|
||||||
options: vec![],
|
options: vec![],
|
||||||
values: vec![],
|
values: vec![],
|
||||||
media: vec![],
|
media: vec![],
|
||||||
|
@ -157,6 +161,7 @@ mod tests {
|
||||||
type_: FieldType::ListMulti,
|
type_: FieldType::ListMulti,
|
||||||
label: None,
|
label: None,
|
||||||
required: false,
|
required: false,
|
||||||
|
desc: None,
|
||||||
options: vec![],
|
options: vec![],
|
||||||
values: vec![],
|
values: vec![],
|
||||||
media: vec![],
|
media: vec![],
|
||||||
|
@ -166,6 +171,7 @@ mod tests {
|
||||||
type_: FieldType::ListMulti,
|
type_: FieldType::ListMulti,
|
||||||
label: None,
|
label: None,
|
||||||
required: false,
|
required: false,
|
||||||
|
desc: None,
|
||||||
options: vec![],
|
options: vec![],
|
||||||
values: vec![
|
values: vec![
|
||||||
String::from("xmpp:security@foo.bar"),
|
String::from("xmpp:security@foo.bar"),
|
||||||
|
@ -178,6 +184,7 @@ mod tests {
|
||||||
type_: FieldType::ListMulti,
|
type_: FieldType::ListMulti,
|
||||||
label: None,
|
label: None,
|
||||||
required: false,
|
required: false,
|
||||||
|
desc: None,
|
||||||
options: vec![],
|
options: vec![],
|
||||||
values: vec![String::from("mailto:support@foo.bar")],
|
values: vec![String::from("mailto:support@foo.bar")],
|
||||||
media: vec![],
|
media: vec![],
|
||||||
|
|
Loading…
Reference in a new issue