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 try_from::TryFrom;
 10
 11/// Structure representing a `http://jabber.org/network/serverinfo` form type.
 12#[derive(Debug, Clone)]
 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 Err = 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 {
 44            abuse: vec![],
 45            admin: vec![],
 46            feedback: vec![],
 47            sales: vec![],
 48            security: vec![],
 49            support: vec![],
 50        };
 51        for field in form.fields {
 52            if field.type_ != FieldType::ListMulti {
 53                return Err(Error::ParseError("Field is not of the required type."));
 54            }
 55            if field.var == "abuse-addresses" {
 56                server_info.abuse = field.values;
 57            } else if field.var == "admin-addresses" {
 58                server_info.admin = field.values;
 59            } else if field.var == "feedback-addresses" {
 60                server_info.feedback = field.values;
 61            } else if field.var == "sales-addresses" {
 62                server_info.sales = field.values;
 63            } else if field.var == "security-addresses" {
 64                server_info.security = field.values;
 65            } else if field.var == "support-addresses" {
 66                server_info.support = field.values;
 67            } else {
 68                return Err(Error::ParseError("Unknown form field var."));
 69            }
 70        }
 71
 72        Ok(server_info)
 73    }
 74}
 75
 76impl From<ServerInfo> for DataForm {
 77    fn from(server_info: ServerInfo) -> DataForm {
 78        DataForm {
 79            type_: DataFormType::Result_,
 80            form_type: Some(String::from(ns::SERVER_INFO)),
 81            title: None,
 82            instructions: None,
 83            fields: vec![
 84                Field {
 85                    var: String::from("FORM_TYPE"),
 86                    type_: FieldType::Hidden,
 87                    label: None,
 88                    required: false,
 89                    options: vec![],
 90                    values: vec![String::from(ns::SERVER_INFO)],
 91                    media: vec![],
 92                },
 93                generate_address_field("abuse-addresses", server_info.abuse),
 94                generate_address_field("admin-addresses", server_info.admin),
 95                generate_address_field("feedback-addresses", server_info.feedback),
 96                generate_address_field("sales-addresses", server_info.sales),
 97                generate_address_field("security-addresses", server_info.security),
 98                generate_address_field("support-addresses", server_info.support),
 99            ],
100        }
101    }
102}
103
104/// Generate `Field` for addresses
105pub fn generate_address_field<S: Into<String>>(var: S, values: Vec<String>) -> Field {
106    Field {
107        var: var.into(),
108        type_: FieldType::ListMulti,
109        label: None,
110        required: false,
111        options: vec![],
112        values,
113        media: vec![],
114    }
115}
116
117#[cfg(test)]
118mod tests {
119    use super::*;
120    use crate::data_forms::{DataForm, DataFormType, Field, FieldType};
121
122    #[cfg(target_pointer_width = "32")]
123    #[test]
124    fn test_size() {
125        assert_size!(ServerInfo, 72);
126    }
127
128    #[cfg(target_pointer_width = "64")]
129    #[test]
130    fn test_size() {
131        assert_size!(ServerInfo, 144);
132    }
133
134    #[test]
135    fn test_simple() {
136        let form = DataForm {
137            type_: DataFormType::Result_,
138            form_type: Some(String::from(ns::SERVER_INFO)),
139            title: None,
140            instructions: None,
141            fields: vec![
142                Field {
143                    var: String::from("FORM_TYPE"),
144                    type_: FieldType::Hidden,
145                    label: None,
146                    required: false,
147                    options: vec![],
148                    values: vec![String::from(ns::SERVER_INFO)],
149                    media: vec![],
150                },
151                Field {
152                    var: String::from("abuse-addresses"),
153                    type_: FieldType::ListMulti,
154                    label: None,
155                    required: false,
156                    options: vec![],
157                    values: vec![],
158                    media: vec![],
159                },
160                Field {
161                    var: String::from("admin-addresses"),
162                    type_: FieldType::ListMulti,
163                    label: None,
164                    required: false,
165                    options: vec![],
166                    values: vec![
167                        String::from("xmpp:admin@foo.bar"),
168                        String::from("https://foo.bar/chat/"),
169                        String::from("mailto:admin@foo.bar"),
170                    ],
171                    media: vec![],
172                },
173                Field {
174                    var: String::from("feedback-addresses"),
175                    type_: FieldType::ListMulti,
176                    label: None,
177                    required: false,
178                    options: vec![],
179                    values: vec![],
180                    media: vec![],
181                },
182                Field {
183                    var: String::from("sales-addresses"),
184                    type_: FieldType::ListMulti,
185                    label: None,
186                    required: false,
187                    options: vec![],
188                    values: vec![],
189                    media: vec![],
190                },
191                Field {
192                    var: String::from("security-addresses"),
193                    type_: FieldType::ListMulti,
194                    label: None,
195                    required: false,
196                    options: vec![],
197                    values: vec![
198                        String::from("xmpp:security@foo.bar"),
199                        String::from("mailto:security@foo.bar"),
200                    ],
201                    media: vec![],
202                },
203                Field {
204                    var: String::from("support-addresses"),
205                    type_: FieldType::ListMulti,
206                    label: None,
207                    required: false,
208                    options: vec![],
209                    values: vec![String::from("mailto:support@foo.bar")],
210                    media: vec![],
211                },
212            ],
213        };
214
215        let server_info = ServerInfo {
216            abuse: vec![],
217            admin: vec![
218                String::from("xmpp:admin@foo.bar"),
219                String::from("https://foo.bar/chat/"),
220                String::from("mailto:admin@foo.bar"),
221            ],
222            feedback: vec![],
223            sales: vec![],
224            security: vec![
225                String::from("xmpp:security@foo.bar"),
226                String::from("mailto:security@foo.bar"),
227            ],
228            support: vec![String::from("mailto:support@foo.bar")],
229        };
230
231        // assert_eq!(DataForm::from(server_info), form);
232        // assert_eq!(ServerInfo::try_from(form), Ok(form));
233    }
234}