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 crate::util::error::Error;
  9use std::convert::TryFrom;
 10
 11/// Structure representing a `http://jabber.org/network/serverinfo` form type.
 12#[derive(Debug, Clone, PartialEq, Default)]
 13pub struct ServerInfo {
 14    /// Abuse addresses
 15    pub abuse: Vec<String>,
 16
 17    /// Admin addresses
 18    pub admin: Vec<String>,
 19
 20    /// Feedback addresses
 21    pub feedback: Vec<String>,
 22
 23    /// Sales addresses
 24    pub sales: Vec<String>,
 25
 26    /// Security addresses
 27    pub security: Vec<String>,
 28
 29    /// Support addresses
 30    pub support: Vec<String>,
 31}
 32
 33impl TryFrom<DataForm> for ServerInfo {
 34    type Error = Error;
 35
 36    fn try_from(form: DataForm) -> Result<ServerInfo, Error> {
 37        if form.type_ != DataFormType::Result_ {
 38            return Err(Error::ParseError("Wrong type of form."));
 39        }
 40        if form.form_type != Some(String::from(ns::SERVER_INFO)) {
 41            return Err(Error::ParseError("Wrong FORM_TYPE for form."));
 42        }
 43        let mut server_info = ServerInfo::default();
 44        for field in form.fields {
 45            if field.type_ != FieldType::ListMulti {
 46                return Err(Error::ParseError("Field is not of the required type."));
 47            }
 48            if field.var == "abuse-addresses" {
 49                server_info.abuse = field.values;
 50            } else if field.var == "admin-addresses" {
 51                server_info.admin = field.values;
 52            } else if field.var == "feedback-addresses" {
 53                server_info.feedback = field.values;
 54            } else if field.var == "sales-addresses" {
 55                server_info.sales = field.values;
 56            } else if field.var == "security-addresses" {
 57                server_info.security = field.values;
 58            } else if field.var == "support-addresses" {
 59                server_info.support = field.values;
 60            } else {
 61                return Err(Error::ParseError("Unknown form field var."));
 62            }
 63        }
 64
 65        Ok(server_info)
 66    }
 67}
 68
 69impl From<ServerInfo> for DataForm {
 70    fn from(server_info: ServerInfo) -> DataForm {
 71        DataForm {
 72            type_: DataFormType::Result_,
 73            form_type: Some(String::from(ns::SERVER_INFO)),
 74            title: None,
 75            instructions: None,
 76            fields: vec![
 77                generate_address_field("abuse-addresses", server_info.abuse),
 78                generate_address_field("admin-addresses", server_info.admin),
 79                generate_address_field("feedback-addresses", server_info.feedback),
 80                generate_address_field("sales-addresses", server_info.sales),
 81                generate_address_field("security-addresses", server_info.security),
 82                generate_address_field("support-addresses", server_info.support),
 83            ],
 84        }
 85    }
 86}
 87
 88/// Generate `Field` for addresses
 89pub fn generate_address_field<S: Into<String>>(var: S, values: Vec<String>) -> Field {
 90    Field {
 91        var: var.into(),
 92        type_: FieldType::ListMulti,
 93        label: None,
 94        required: false,
 95        options: vec![],
 96        values,
 97        media: vec![],
 98    }
 99}
100
101#[cfg(test)]
102mod tests {
103    use super::*;
104    use crate::data_forms::{DataForm, DataFormType, Field, FieldType};
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 {
121            type_: DataFormType::Result_,
122            form_type: Some(String::from(ns::SERVER_INFO)),
123            title: None,
124            instructions: None,
125            fields: vec![
126                Field {
127                    var: String::from("abuse-addresses"),
128                    type_: FieldType::ListMulti,
129                    label: None,
130                    required: false,
131                    options: vec![],
132                    values: vec![],
133                    media: vec![],
134                },
135                Field {
136                    var: String::from("admin-addresses"),
137                    type_: FieldType::ListMulti,
138                    label: None,
139                    required: false,
140                    options: vec![],
141                    values: vec![
142                        String::from("xmpp:admin@foo.bar"),
143                        String::from("https://foo.bar/chat/"),
144                        String::from("mailto:admin@foo.bar"),
145                    ],
146                    media: vec![],
147                },
148                Field {
149                    var: String::from("feedback-addresses"),
150                    type_: FieldType::ListMulti,
151                    label: None,
152                    required: false,
153                    options: vec![],
154                    values: vec![],
155                    media: vec![],
156                },
157                Field {
158                    var: String::from("sales-addresses"),
159                    type_: FieldType::ListMulti,
160                    label: None,
161                    required: false,
162                    options: vec![],
163                    values: vec![],
164                    media: vec![],
165                },
166                Field {
167                    var: String::from("security-addresses"),
168                    type_: FieldType::ListMulti,
169                    label: None,
170                    required: false,
171                    options: vec![],
172                    values: vec![
173                        String::from("xmpp:security@foo.bar"),
174                        String::from("mailto:security@foo.bar"),
175                    ],
176                    media: vec![],
177                },
178                Field {
179                    var: String::from("support-addresses"),
180                    type_: FieldType::ListMulti,
181                    label: None,
182                    required: false,
183                    options: vec![],
184                    values: vec![String::from("mailto:support@foo.bar")],
185                    media: vec![],
186                },
187            ],
188        };
189
190        let server_info = ServerInfo {
191            abuse: vec![],
192            admin: vec![
193                String::from("xmpp:admin@foo.bar"),
194                String::from("https://foo.bar/chat/"),
195                String::from("mailto:admin@foo.bar"),
196            ],
197            feedback: vec![],
198            sales: vec![],
199            security: vec![
200                String::from("xmpp:security@foo.bar"),
201                String::from("mailto:security@foo.bar"),
202            ],
203            support: vec![String::from("mailto:support@foo.bar")],
204        };
205
206        // assert_eq!(DataForm::from(server_info), form);
207        assert_eq!(ServerInfo::try_from(form).unwrap(), server_info);
208    }
209}