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}