rooting_forms/lib.rs
1use rooting::{
2 El,
3};
4pub use rooting_forms_proc_macros::Form;
5
6pub struct FormElements {
7 /// The error display element, with `CSS_CLASS_ERROR`. This may be placed before
8 /// the label in a struct context.
9 pub error: Option<El>,
10 /// The input, and any additional controls.
11 pub elements: Vec<El>,
12}
13
14/// An object representing a form (the state of the form).
15pub trait FormState<T> {
16 /// Parse the elements into the resulting type.
17 fn parse(&self) -> Result<T, ()>;
18}
19
20/// Provides methods for creating forms from a type. All types that can appear as
21/// or within such forms must implement this. This is automatically implemented for
22/// `FormWith<()>` so if implementing yourself, focus on that trait.
23pub trait Form {
24 /// Generates a form state manager to produce form elements and parse the entered
25 /// values.
26 ///
27 /// * `field` - is the field name, for accessibility using `aria-label`. `<label>`
28 /// isn't used sometime due to anonymous fields in tuples.
29 ///
30 /// * `from` - data used to populate the initial form, for example if creating a form
31 /// to edit existing data.
32 fn new_form(field: &str, from: Option<&Self>) -> (FormElements, Box<dyn FormState<Self>>);
33}
34
35/// Like `Form` but allows passing in additional context, for custom elements that
36/// need it. `FormWith<()>` is generated by the `Form` derive macro.
37pub trait FormWith<C> {
38 /// Generates a form state manager to produce form elements and parse the entered
39 /// values.
40 ///
41 /// * `context` - any additional data to be used when generating form states and
42 /// elements. This is forwarded to all nested `new_form` calls.
43 ///
44 /// See `Form` for the other fields.
45 fn new_form_with(context: &C, field: &str, from: Option<&Self>) -> (FormElements, Box<dyn FormState<Self>>) {
46 return Self::new_form_with_(context, field, from, 0);
47 }
48 fn new_form_with_(
49 context: &C,
50 field: &str,
51 from: Option<&Self>,
52 depth: usize,
53 ) -> (FormElements, Box<dyn FormState<Self>>);
54}
55
56impl<T: FormWith<()>> Form for T {
57 fn new_form(field: &str, from: Option<&Self>) -> (FormElements, Box<dyn FormState<Self>>) {
58 return T::new_form_with(&(), field, from);
59 }
60}
61pub mod css;
62pub mod impl_str;
63pub mod impl_password;
64pub mod impl_bool;
65pub mod impl_option;
66pub mod impl_unit_structs;
67pub mod impl_vec;
68pub mod impl_macroutil;
69#[cfg(feature = "jiff")]
70pub mod impl_jiff;
71
72/// Republished types for macro use.
73pub mod republish {
74 pub use web_sys::HtmlSelectElement;
75}