Skip to content

Allow using enums in form easily #356

@m4tx

Description

@m4tx

Now with #351 merged, we have an easy way to derive SelectChoice for user-defined enums. However, its usefulness is quite limited, as there is still no obvious way to use them in forms, because they do not implement AsFormField.

For Weekday, we implement AsFormField manually:

impl AsFormField for Weekday {
type Type = SelectField<Self>;
fn clean_value(field: &Self::Type) -> Result<Self, FormFieldValidationError> {
let value = check_required(field)?;
Self::from_str(value)
}
fn to_field_value(&self) -> String {
<Self as SelectChoice>::to_string(self)
}
}
macro_rules! impl_as_form_field_mult {
($field_type:ty) => {
impl_as_form_field_mult_collection!(::std::vec::Vec<$field_type>, $field_type);
impl_as_form_field_mult_collection!(::std::collections::VecDeque<$field_type>, $field_type);
impl_as_form_field_mult_collection!(
::std::collections::LinkedList<$field_type>,
$field_type
);
impl_as_form_field_mult_collection!(::std::collections::HashSet<$field_type>, $field_type);
impl_as_form_field_mult_collection!(::indexmap::IndexSet<$field_type>, $field_type);
};
}
macro_rules! impl_as_form_field_mult_collection {
($collection_type:ty, $field_type:ty) => {
impl AsFormField for $collection_type {
type Type = SelectMultipleField<$field_type>;
fn clean_value(field: &Self::Type) -> Result<Self, FormFieldValidationError> {
let value = check_required_multiple(field)?;
value.iter().map(|id| <$field_type>::from_str(id)).collect()
}
fn to_field_value(&self) -> String {
String::new()
}
}
};
}
impl_as_form_field_mult!(Weekday);
impl_as_form_field_mult_collection!(WeekdaySet, Weekday);

For user-defined enums, I think there are two possible ways to tackle this:

  1. Add a derive macro that would create generic AsFormField impls for the enum as well as Vec<T>, HashSet<T>, etc., similarly to the ones for Weekday.
  2. Add wrapper structs (e.g. Choice and ChoiceMultiple) that would contain the enum implementing SelectChoice, and a Vec of these, respectively.

Which of these would be more appropriate is subject to discussion.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions