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    }
 99}
100
101#[cfg(test)]
102mod tests {
103    use super::*;
104
105    #[cfg(target_pointer_width = "32")]
106    #[test]
107    fn test_size() {
108        assert_size!(ServerInfo, 72);
109    }
110
111    #[cfg(target_pointer_width = "64")]
112    #[test]
113    fn test_size() {
114        assert_size!(ServerInfo, 144);
115    }
116
117    #[test]
118    fn test_simple() {
119        let form = DataForm::new(
120            DataFormType::Result_,
121            ns::SERVER_INFO,
122            vec![
123                Field::new("abuse-addresses", FieldType::ListMulti),
124                Field::new("admin-addresses", FieldType::ListMulti)
125                    .with_value("xmpp:admin@foo.bar")
126                    .with_value("https://foo.bar/chat/")
127                    .with_value("mailto:admin@foo.bar"),
128                Field::new("feedback-addresses", FieldType::ListMulti),
129                Field::new("sales-addresses", FieldType::ListMulti),
130                Field::new("security-addresses", FieldType::ListMulti)
131                    .with_value("xmpp:security@foo.bar")
132                    .with_value("mailto:security@foo.bar"),
133                Field::new("support-addresses", FieldType::ListMulti)
134                    .with_value("mailto:support@foo.bar"),
135            ],
136        );
137
138        let server_info = ServerInfo {
139            abuse: vec![],
140            admin: vec![
141                String::from("xmpp:admin@foo.bar"),
142                String::from("https://foo.bar/chat/"),
143                String::from("mailto:admin@foo.bar"),
144            ],
145            feedback: vec![],
146            sales: vec![],
147            security: vec![
148                String::from("xmpp:security@foo.bar"),
149                String::from("mailto:security@foo.bar"),
150            ],
151            support: vec![String::from("mailto:support@foo.bar")],
152        };
153
154        // assert_eq!(DataForm::from(server_info), form);
155        assert_eq!(ServerInfo::try_from(form).unwrap(), server_info);
156    }
157}