Skip to main content

tablo_core/schema/
input.rs

1//! A typed value a form posts under keys no column binds: the [`FormInput`] trait.
2
3use topcoat::context::Cx;
4
5use super::{Field, Schema};
6use crate::values::{FieldError, FormValues};
7
8/// A typed value a form posts under its own keys, which no column binds: what an
9/// [`Action`](crate::Action) asks for before it runs, what a sign-up reads, one item of a
10/// repeater.
11///
12/// Derive it with [`FormInput`](derive@crate::FormInput) on a struct of form scalars, or name
13/// `()` for a value that asks for nothing.
14///
15/// An action with input asks for it before it runs: its button opens the input form in a dialog
16/// over the page, and its submit runs the action with the parsed value. A refused value renders
17/// the form as a page with the field's error, and writes nothing.
18///
19/// A repeater stores its items in a `#[document]` list, so an item is also a `toasty::Embed`
20/// struct. Each row posts the item's keys under its own prefix, and [`write`](Self::write) fills
21/// a stored item's row on the edit page.
22pub trait FormInput: Sized + Send + Sync + 'static {
23    /// The value's controls, each posting its own key. An empty schema asks for nothing: an
24    /// action runs on its button.
25    fn schema() -> Schema;
26
27    /// Parse a submission of [`schema`](Self::schema)'s keys.
28    ///
29    /// # Errors
30    ///
31    /// Every key that failed, each once.
32    fn parse(cx: &Cx, values: &FormValues) -> Result<Self, Vec<FieldError>>;
33
34    /// Write the value's keys as its form posts them: a repeater fills a stored item's row from
35    /// them, and its detail-page column reads them. A password writes nothing, as it never renders
36    /// back into a form. Nothing writes an action's input or a sign-up, so a type used only there
37    /// writes nothing too.
38    fn write(&self, out: &mut FormValues);
39}
40
41/// No input: an action runs on its button.
42impl FormInput for () {
43    fn schema() -> Schema {
44        Schema::empty()
45    }
46
47    fn parse(_cx: &Cx, _values: &FormValues) -> Result<Self, Vec<FieldError>> {
48        Ok(())
49    }
50
51    fn write(&self, _out: &mut FormValues) {}
52}
53
54/// Renders `field`'s control required: the derive marks each field with no blank answer.
55#[doc(hidden)]
56pub fn required_input(field: impl Into<Field>) -> Field {
57    let mut field = field.into();
58    field.set_required(true);
59    field
60}