rss/
cloud.rs

1// This file is part of rss.
2//
3// Copyright © 2015-2021 The rust-syndication Developers
4//
5// This program is free software; you can redistribute it and/or modify
6// it under the terms of the MIT License and/or Apache 2.0 License.
7
8use std::io::{BufRead, Write};
9
10use quick_xml::events::{BytesStart, Event};
11use quick_xml::Error as XmlError;
12use quick_xml::Reader;
13use quick_xml::Writer;
14
15use crate::error::Error;
16use crate::toxml::ToXml;
17use crate::util::{attr_value, decode, skip};
18
19/// Represents a cloud in an RSS feed.
20#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
21#[derive(Debug, Default, Clone, PartialEq)]
22#[cfg_attr(feature = "builders", derive(Builder))]
23#[cfg_attr(
24    feature = "builders",
25    builder(
26        setter(into),
27        default,
28        build_fn(name = "build_impl", private, error = "never::Never")
29    )
30)]
31pub struct Cloud {
32    /// The domain to register with.
33    pub domain: String,
34    /// The port to register with.
35    pub port: String,
36    /// The path to register with.
37    pub path: String,
38    /// The procedure to register with.
39    pub register_procedure: String,
40    /// The protocol to register with.
41    pub protocol: String,
42}
43
44impl Cloud {
45    /// Return the domain for this cloud.
46    ///
47    /// # Examples
48    ///
49    /// ```
50    /// use rss::Cloud;
51    ///
52    /// let mut cloud = Cloud::default();
53    /// cloud.set_domain("http://example.com");
54    /// assert_eq!(cloud.domain(), "http://example.com");
55    /// ```
56    pub fn domain(&self) -> &str {
57        self.domain.as_str()
58    }
59
60    /// Set the domain for this cloud.
61    ///
62    /// # Examples
63    ///
64    /// ```
65    /// use rss::Cloud;
66    ///
67    /// let mut cloud = Cloud::default();
68    /// cloud.set_domain("http://example.com");
69    /// ```
70    pub fn set_domain<V>(&mut self, domain: V)
71    where
72        V: Into<String>,
73    {
74        self.domain = domain.into();
75    }
76
77    /// Return the port for this cloud.
78    ///
79    /// # Examples
80    ///
81    /// ```
82    /// use rss::Cloud;
83    ///
84    /// let mut cloud = Cloud::default();
85    /// cloud.set_port("80");
86    /// assert_eq!(cloud.port(), "80");
87    /// ```
88    pub fn port(&self) -> &str {
89        self.port.as_str()
90    }
91
92    /// Set the port for this cloud.
93    ///
94    /// # Examples
95    ///
96    /// ```
97    /// use rss::Cloud;
98    ///
99    /// let mut cloud = Cloud::default();
100    /// cloud.set_port("80");
101    /// ```
102    pub fn set_port<V>(&mut self, port: V)
103    where
104        V: Into<String>,
105    {
106        self.port = port.into();
107    }
108
109    /// Return the path for this cloud.
110    ///
111    /// # Examples
112    ///
113    /// ```
114    /// use rss::Cloud;
115    ///
116    /// let mut cloud = Cloud::default();
117    /// cloud.set_port("/rpc");
118    /// assert_eq!(cloud.port(), "/rpc");
119    /// ```
120    pub fn path(&self) -> &str {
121        self.path.as_str()
122    }
123
124    /// Set the path for this cloud.
125    ///
126    /// # Examples
127    ///
128    /// ```
129    /// use rss::Cloud;
130    ///
131    /// let mut cloud = Cloud::default();
132    /// cloud.set_path("/rpc");
133    /// ```
134    pub fn set_path<V>(&mut self, path: V)
135    where
136        V: Into<String>,
137    {
138        self.path = path.into();
139    }
140
141    /// Return the register procedure for this cloud.
142    ///
143    /// # Examples
144    ///
145    /// ```
146    /// use rss::Cloud;
147    ///
148    /// let mut cloud = Cloud::default();
149    /// cloud.set_register_procedure("pingMe");
150    /// assert_eq!(cloud.register_procedure(), "pingMe");
151    /// ```
152    pub fn register_procedure(&self) -> &str {
153        self.register_procedure.as_str()
154    }
155
156    /// Set the register procedure for this cloud.
157    ///
158    /// # Examples
159    ///
160    /// ```
161    /// use rss::Cloud;
162    ///
163    /// let mut cloud = Cloud::default();
164    /// cloud.set_register_procedure("pingMe");
165    /// ```
166    pub fn set_register_procedure<V>(&mut self, register_procedure: V)
167    where
168        V: Into<String>,
169    {
170        self.register_procedure = register_procedure.into();
171    }
172
173    /// Return the protocol for this cloud.
174    ///
175    /// # Examples
176    ///
177    /// ```
178    /// use rss::Cloud;
179    ///
180    /// let mut cloud = Cloud::default();
181    /// cloud.set_protocol("xml-rpc");
182    /// assert_eq!(cloud.protocol(), "xml-rpc");
183    /// ```
184    pub fn protocol(&self) -> &str {
185        self.protocol.as_str()
186    }
187
188    /// Set the protocol for this cloud.
189    ///
190    /// # Examples
191    ///
192    /// ```
193    /// use rss::Cloud;
194    ///
195    /// let mut cloud = Cloud::default();
196    /// cloud.set_protocol("xml-rpc");
197    /// ```
198    pub fn set_protocol<V>(&mut self, protocol: V)
199    where
200        V: Into<String>,
201    {
202        self.protocol = protocol.into();
203    }
204}
205
206impl Cloud {
207    /// Builds a Cloud from source XML
208    pub fn from_xml<'s, R: BufRead>(
209        reader: &mut Reader<R>,
210        element: &'s BytesStart<'s>,
211    ) -> Result<Self, Error> {
212        let mut cloud = Cloud::default();
213
214        for att in element.attributes().with_checks(false).flatten() {
215            match decode(att.key.as_ref(), reader)?.as_ref() {
216                "domain" => cloud.domain = attr_value(&att, reader)?.to_string(),
217                "port" => cloud.port = attr_value(&att, reader)?.to_string(),
218                "path" => cloud.path = attr_value(&att, reader)?.to_string(),
219                "registerProcedure" => {
220                    cloud.register_procedure = attr_value(&att, reader)?.to_string()
221                }
222                "protocol" => cloud.protocol = attr_value(&att, reader)?.to_string(),
223                _ => {}
224            }
225        }
226
227        skip(element.name(), reader)?;
228
229        Ok(cloud)
230    }
231}
232
233impl ToXml for Cloud {
234    fn to_xml<W: Write>(&self, writer: &mut Writer<W>) -> Result<(), XmlError> {
235        let name = "cloud";
236        let mut element = BytesStart::new(name);
237
238        element.push_attribute(("domain", self.domain.as_str()));
239        element.push_attribute(("port", self.port.as_str()));
240        element.push_attribute(("path", self.path.as_str()));
241        element.push_attribute(("registerProcedure", self.register_procedure.as_str()));
242        element.push_attribute(("protocol", self.protocol.as_str()));
243
244        writer.write_event(Event::Empty(element))?;
245        Ok(())
246    }
247}
248
249#[cfg(feature = "builders")]
250impl CloudBuilder {
251    /// Builds a new `Cloud`.
252    pub fn build(&self) -> Cloud {
253        self.build_impl().unwrap()
254    }
255}