use super::{FieldError, FormScalar, FormValue, FormValues, unreadable};
pub fn parse_scalar<T: FormScalar>(
key: &str,
values: &FormValues,
blank: Option<T>,
) -> std::result::Result<T, FieldError> {
let raw = match values.get(key) {
None => "",
Some(FormValue::Text(text)) => text.trim(),
Some(_) => return Err(unreadable(key)),
};
if raw.is_empty() {
return blank.ok_or_else(|| FieldError::required(key));
}
T::parse_form(raw).map_err(|message| FieldError::invalid(key, message))
}
pub fn parse_password(
key: &str,
values: &FormValues,
blank: Option<String>,
) -> std::result::Result<String, FieldError> {
parse_scalar::<String>(key, values, blank)?;
Ok(values.text(key).unwrap_or_default().to_string())
}
pub fn write_list<'a, T: FormScalar + 'a>(values: impl IntoIterator<Item = &'a T>) -> FormValue {
FormValue::List(values.into_iter().map(T::to_form).collect())
}
pub fn parse_list<T: FormScalar>(
key: &str,
values: &FormValues,
) -> std::result::Result<Vec<T>, FieldError> {
let items: &[String] = match values.get(key) {
None => &[],
Some(FormValue::List(items)) => items,
Some(_) => return Err(unreadable(key)),
};
items
.iter()
.map(|item| T::parse_form(item).map_err(|message| FieldError::invalid(key, message)))
.collect()
}
#[cfg(test)]
mod tests;