1mod error;
8mod parse;
9mod scalar;
10mod typed;
11mod zone;
12
13use std::collections::BTreeMap;
14
15pub(crate) use error::unreadable;
16pub use error::{FieldError, FieldErrorKind, FieldErrors};
17pub use parse::{parse_list, parse_password, parse_scalar, write_list};
18pub use scalar::{FormScalar, NullableScalar, assert_form_scalar};
19pub use typed::TypedValue;
20pub(crate) use typed::{is_email, is_web_url, read_datetime_local};
21pub(crate) use zone::ZoneSource;
22pub use zone::time_zone;
23
24#[derive(Debug, Clone, Default, PartialEq, Eq)]
44pub struct FormValues {
45 values: BTreeMap<String, FormValue>,
46}
47
48impl FormValues {
49 pub fn new() -> Self {
51 Self::default()
52 }
53
54 pub fn is_empty(&self) -> bool {
56 self.values.is_empty()
57 }
58
59 pub fn len(&self) -> usize {
61 self.values.len()
62 }
63
64 pub fn get(&self, key: &str) -> Option<&FormValue> {
66 self.values.get(key)
67 }
68
69 pub fn text(&self, key: &str) -> Option<&str> {
71 self.get(key).and_then(FormValue::as_text)
72 }
73
74 pub fn list(&self, key: &str) -> Option<&[String]> {
76 self.get(key).and_then(FormValue::as_list)
77 }
78
79 pub fn rows(&self, key: &str) -> Option<&[FormValues]> {
81 self.get(key).and_then(FormValue::as_rows)
82 }
83
84 pub fn contains(&self, key: &str) -> bool {
86 self.values.contains_key(key)
87 }
88
89 pub fn insert(
91 &mut self,
92 key: impl Into<String>,
93 value: impl Into<FormValue>,
94 ) -> Option<FormValue> {
95 self.values.insert(key.into(), value.into())
96 }
97
98 pub fn remove(&mut self, key: &str) -> Option<FormValue> {
100 self.values.remove(key)
101 }
102
103 pub fn keys(&self) -> impl Iterator<Item = &str> {
105 self.values.keys().map(String::as_str)
106 }
107
108 pub fn iter(&self) -> impl Iterator<Item = (&str, &FormValue)> {
110 self.values.iter().map(|(key, value)| (key.as_str(), value))
111 }
112}
113
114impl<K: Into<String>, V: Into<FormValue>> FromIterator<(K, V)> for FormValues {
115 fn from_iter<I: IntoIterator<Item = (K, V)>>(iter: I) -> Self {
116 let mut values = Self::new();
117 values.extend(iter);
118 values
119 }
120}
121
122impl<K: Into<String>, V: Into<FormValue>> Extend<(K, V)> for FormValues {
124 fn extend<I: IntoIterator<Item = (K, V)>>(&mut self, iter: I) {
125 for (key, value) in iter {
126 self.insert(key, value);
127 }
128 }
129}
130
131impl IntoIterator for FormValues {
132 type Item = (String, FormValue);
133 type IntoIter = std::collections::btree_map::IntoIter<String, FormValue>;
134
135 fn into_iter(self) -> Self::IntoIter {
136 self.values.into_iter()
137 }
138}
139
140#[derive(Debug, Clone, PartialEq, Eq)]
142#[non_exhaustive]
143pub enum FormValue {
144 Text(String),
147 List(Vec<String>),
150 Rows(Vec<FormValues>),
152}
153
154impl FormValue {
155 pub fn as_text(&self) -> Option<&str> {
157 match self {
158 Self::Text(text) => Some(text),
159 _ => None,
160 }
161 }
162
163 pub fn as_list(&self) -> Option<&[String]> {
165 match self {
166 Self::List(items) => Some(items),
167 _ => None,
168 }
169 }
170
171 pub fn as_rows(&self) -> Option<&[FormValues]> {
173 match self {
174 Self::Rows(rows) => Some(rows),
175 _ => None,
176 }
177 }
178}
179
180impl From<String> for FormValue {
181 fn from(text: String) -> Self {
182 Self::Text(text)
183 }
184}
185
186impl From<&str> for FormValue {
187 fn from(text: &str) -> Self {
188 Self::Text(text.to_string())
189 }
190}
191
192impl From<&String> for FormValue {
193 fn from(text: &String) -> Self {
194 Self::Text(text.clone())
195 }
196}
197
198impl From<Vec<String>> for FormValue {
199 fn from(items: Vec<String>) -> Self {
200 Self::List(items)
201 }
202}
203
204impl From<Vec<FormValues>> for FormValue {
205 fn from(rows: Vec<FormValues>) -> Self {
206 Self::Rows(rows)
207 }
208}
209
210#[derive(Debug, Clone)]
212pub struct FormField<K> {
213 pub field: K,
215 pub name: &'static str,
217 pub keys: Vec<String>,
221 pub required: Vec<String>,
224}