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}