xmpp_parsers/
server_info.rs

1// Copyright (C) 2019 Maxime “pep” Buquet <pep@bouah.net>
2// This Source Code Form is subject to the terms of the Mozilla Public
3// License, v. 2.0. If a copy of the MPL was not distributed with this
4// file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
6use crate::data_forms::{DataForm, DataFormType, Field, FieldType};
7use crate::ns;
8use xso::error::Error;
9
10/// Structure representing a `http://jabber.org/network/serverinfo` form type.
11#[derive(Debug, Clone, PartialEq, Default)]
12pub struct ServerInfo {
13    /// Abuse addresses
14    pub abuse: Vec<String>,
15
16    /// Admin addresses
17    pub admin: Vec<String>,
18
19    /// Feedback addresses
20    pub feedback: Vec<String>,
21
22    /// Sales addresses
23    pub sales: Vec<String>,
24
25    /// Security addresses
26    pub security: Vec<String>,
27
28    /// Support addresses
29    pub support: Vec<String>,
30}
31
32impl TryFrom<DataForm> for ServerInfo {
33    type Error = Error;
34
35    fn try_from(form: DataForm) -> Result<ServerInfo, Error> {
36        if form.type_ != DataFormType::Result_ {
37            return Err(Error::Other("Wrong type of form."));
38        }
39        if form.form_type != Some(String::from(ns::SERVER_INFO)) {
40            return Err(Error::Other("Wrong FORM_TYPE for form."));
41        }
42        let mut server_info = ServerInfo::default();
43        for field in form.fields {
44            if field.type_ != FieldType::ListMulti {
45                return Err(Error::Other("Field is not of the required type."));
46            }
47            if field.var.as_deref() == Some("abuse-addresses") {
48                server_info.abuse = field.values;
49            } else if field.var.as_deref() == Some("admin-addresses") {
50                server_info.admin = field.values;
51            } else if field.var.as_deref() == Some("feedback-addresses") {
52                server_info.feedback = field.values;
53            } else if field.var.as_deref() == Some("sales-addresses") {
54                server_info.sales = field.values;
55            } else if field.var.as_deref() == Some("security-addresses") {
56                server_info.security = field.values;
57            } else if field.var.as_deref() == Some("support-addresses") {
58                server_info.support = field.values;
59            } else {
60                return Err(Error::Other("Unknown form field var."));
61            }
62        }
63
64        Ok(server_info)
65    }
66}
67
68impl From<ServerInfo> for DataForm {
69    fn from(server_info: ServerInfo) -> DataForm {
70        DataForm {
71            type_: DataFormType::Result_,
72            form_type: Some(String::from(ns::SERVER_INFO)),
73            title: None,
74            instructions: None,
75            fields: vec![
76                generate_address_field("abuse-addresses", server_info.abuse),
77                generate_address_field("admin-addresses", server_info.admin),
78                generate_address_field("feedback-addresses", server_info.feedback),
79                generate_address_field("sales-addresses", server_info.sales),
80                generate_address_field("security-addresses", server_info.security),
81                generate_address_field("support-addresses", server_info.support),
82            ],
83        }
84    }
85}
86
87/// Generate `Field` for addresses
88pub fn generate_address_field<S: Into<String>>(var: S, values: Vec<String>) -> Field {
89    Field {
90        var: Some(var.into()),
91        type_: FieldType::ListMulti,
92        label: None,
93        required: false,
94        desc: None,
95        options: vec![],
96        values,
97        media: vec![],
98        validate: None,
99    }
100}
101
102#[cfg(test)]
103mod tests {
104    use super::*;
105
106    #[cfg(target_pointer_width = "32")]
107    #[test]
108    fn test_size() {
109        assert_size!(ServerInfo, 72);
110    }
111
112    #[cfg(target_pointer_width = "64")]
113    #[test]
114    fn test_size() {
115        assert_size!(ServerInfo, 144);
116    }
117
118    #[test]
119    fn test_simple() {
120        let form = DataForm::new(
121            DataFormType::Result_,
122            ns::SERVER_INFO,
123            vec![
124                Field::new("abuse-addresses", FieldType::ListMulti),
125                Field::new("admin-addresses", FieldType::ListMulti)
126                    .with_value("xmpp:admin@foo.bar")
127                    .with_value("https://foo.bar/chat/")
128                    .with_value("mailto:admin@foo.bar"),
129                Field::new("feedback-addresses", FieldType::ListMulti),
130                Field::new("sales-addresses", FieldType::ListMulti),
131                Field::new("security-addresses", FieldType::ListMulti)
132                    .with_value("xmpp:security@foo.bar")
133                    .with_value("mailto:security@foo.bar"),
134                Field::new("support-addresses", FieldType::ListMulti)
135                    .with_value("mailto:support@foo.bar"),
136            ],
137        );
138
139        let server_info = ServerInfo {
140            abuse: vec![],
141            admin: vec![
142                String::from("xmpp:admin@foo.bar"),
143                String::from("https://foo.bar/chat/"),
144                String::from("mailto:admin@foo.bar"),
145            ],
146            feedback: vec![],
147            sales: vec![],
148            security: vec![
149                String::from("xmpp:security@foo.bar"),
150                String::from("mailto:security@foo.bar"),
151            ],
152            support: vec![String::from("mailto:support@foo.bar")],
153        };
154
155        // assert_eq!(DataForm::from(server_info), form);
156        assert_eq!(ServerInfo::try_from(form).unwrap(), server_info);
157    }
158}