rss_for_mikan/
textinput.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::attributes::Attributes;
11use quick_xml::events::{BytesEnd, BytesStart, Event};
12use quick_xml::Error as XmlError;
13use quick_xml::Reader;
14use quick_xml::Writer;
15
16use crate::error::Error;
17use crate::toxml::{ToXml, WriterExt};
18use crate::util::{decode, element_text, skip};
19
20/// Represents a text input for an RSS channel.
21#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
22#[derive(Debug, Default, Clone, PartialEq)]
23#[cfg_attr(feature = "builders", derive(Builder))]
24#[cfg_attr(
25    feature = "builders",
26    builder(
27        setter(into),
28        default,
29        build_fn(name = "build_impl", private, error = "never::Never")
30    )
31)]
32pub struct TextInput {
33    /// The label of the Submit button for the text input.
34    pub title: String,
35    /// A description of the text input.
36    pub description: String,
37    /// The name of the text object.
38    pub name: String,
39    /// The URL of the CGI script that processes the text input request.
40    pub link: String,
41}
42
43impl TextInput {
44    /// Return the title for this text field.
45    ///
46    /// # Examples
47    ///
48    /// ```
49    /// use rss::TextInput;
50    ///
51    /// let mut text_input = TextInput::default();
52    /// text_input.set_title("Input Title");
53    /// assert_eq!(text_input.title(), "Input Title");
54    /// ```
55    pub fn title(&self) -> &str {
56        self.title.as_str()
57    }
58
59    /// Set the title for this text field.
60    ///
61    /// # Examples
62    ///
63    /// ```
64    /// use rss::TextInput;
65    ///
66    /// let mut text_input = TextInput::default();
67    /// text_input.set_title("Input Title");
68    /// ```
69    pub fn set_title<V>(&mut self, title: V)
70    where
71        V: Into<String>,
72    {
73        self.title = title.into();
74    }
75
76    /// Return the description of this text field.
77    ///
78    /// # Examples
79    ///
80    /// ```
81    /// use rss::TextInput;
82    ///
83    /// let mut text_input = TextInput::default();
84    /// text_input.set_description("Input description");
85    /// assert_eq!(text_input.description(), "Input description");
86    /// ```
87    pub fn description(&self) -> &str {
88        self.description.as_str()
89    }
90
91    /// Set the description of this text field.
92    ///
93    /// # Examples
94    ///
95    /// ```
96    /// use rss::TextInput;
97    ///
98    /// let mut text_input = TextInput::default();
99    /// text_input.set_description("Input description");
100    /// ```
101    pub fn set_description<V>(&mut self, description: V)
102    where
103        V: Into<String>,
104    {
105        self.description = description.into();
106    }
107
108    /// Return the name of the text object in this input.
109    ///
110    /// # Examples
111    ///
112    /// ```
113    /// use rss::TextInput;
114    ///
115    /// let mut text_input = TextInput::default();
116    /// text_input.set_name("Input name");
117    /// assert_eq!(text_input.name(), "Input name");
118    /// ```
119    pub fn name(&self) -> &str {
120        self.name.as_str()
121    }
122
123    /// Set the name of the text object in this input.
124    ///
125    /// # Examples
126    ///
127    /// ```
128    /// use rss::TextInput;
129    ///
130    /// let mut text_input = TextInput::default();
131    /// text_input.set_name("Input name");;
132    /// ```
133    pub fn set_name<V>(&mut self, name: V)
134    where
135        V: Into<String>,
136    {
137        self.name = name.into();
138    }
139
140    /// Return the URL of the GCI script that processes the text input request.
141    ///
142    /// # Examples
143    ///
144    /// ```
145    /// use rss::TextInput;
146    ///
147    /// let mut text_input = TextInput::default();
148    /// text_input.set_link("http://example.com/submit");
149    /// assert_eq!(text_input.link(), "http://example.com/submit");
150    /// ```
151    pub fn link(&self) -> &str {
152        self.link.as_str()
153    }
154
155    /// Set the URL of the GCI script that processes the text input request.
156    ///
157    /// # Examples
158    ///
159    /// ```
160    /// use rss::TextInput;
161    ///
162    /// let mut text_input = TextInput::default();
163    /// text_input.set_link("http://example.com/submit");
164    /// ```
165    pub fn set_link<V>(&mut self, link: V)
166    where
167        V: Into<String>,
168    {
169        self.link = link.into();
170    }
171}
172
173impl TextInput {
174    /// Builds a TextInput from source XML
175    pub fn from_xml<R: BufRead>(reader: &mut Reader<R>, _: Attributes) -> Result<Self, Error> {
176        let mut text_input = TextInput::default();
177        let mut buf = Vec::new();
178
179        loop {
180            match reader.read_event_into(&mut buf)? {
181                Event::Start(element) => match decode(element.name().as_ref(), reader)?.as_ref() {
182                    "title" => text_input.title = element_text(reader)?.unwrap_or_default(),
183                    "description" => {
184                        text_input.description = element_text(reader)?.unwrap_or_default()
185                    }
186                    "name" => text_input.name = element_text(reader)?.unwrap_or_default(),
187                    "link" => text_input.link = element_text(reader)?.unwrap_or_default(),
188                    _ => skip(element.name(), reader)?,
189                },
190                Event::End(_) => break,
191                Event::Eof => return Err(Error::Eof),
192                _ => {}
193            }
194
195            buf.clear();
196        }
197
198        Ok(text_input)
199    }
200}
201
202impl ToXml for TextInput {
203    fn to_xml<W: Write>(&self, writer: &mut Writer<W>) -> Result<(), XmlError> {
204        let name = "textInput";
205
206        writer.write_event(Event::Start(BytesStart::new(name)))?;
207
208        writer.write_text_element("title", &self.title)?;
209        writer.write_text_element("description", &self.description)?;
210        writer.write_text_element("name", &self.name)?;
211        writer.write_text_element("link", &self.link)?;
212
213        writer.write_event(Event::End(BytesEnd::new(name)))?;
214        Ok(())
215    }
216}
217
218#[cfg(feature = "builders")]
219impl TextInputBuilder {
220    /// Builds a new `TextInput`.
221    pub fn build(&self) -> TextInput {
222        self.build_impl().unwrap()
223    }
224}