derived_cms/
input.rs

1use std::fmt::Debug;
2
3pub use derived_cms_derive::Input;
4use i18n_embed::fluent::FluentLanguageLoader;
5use maud::Markup;
6
7use crate::{context::ContextTrait, render::FormRenderContext};
8
9/// A property of an entity or nested within another property that can be input in a HTML form
10pub trait Input<S: ContextTrait>: Debug {
11    fn render_input(
12        value: Option<&Self>,
13        name: &str,
14        title: &str,
15        required: bool,
16        ctx: &FormRenderContext<'_, S>,
17        i18n: &FluentLanguageLoader,
18    ) -> Markup;
19}
20
21/// object safe trait that is automatically implemented for [`Option<T>`] where `T` implements [`Input`]
22pub trait DynInput<S: ContextTrait>: Debug {
23    fn render_input(
24        &self,
25        name: &str,
26        title: &str,
27        required: bool,
28        ctx: &FormRenderContext<'_, S>,
29        i18n: &FluentLanguageLoader,
30    ) -> Markup;
31}
32
33impl<T: Input<S>, S: ContextTrait> DynInput<S> for Option<&T> {
34    fn render_input(
35        &self,
36        name: &str,
37        title: &str,
38        required: bool,
39        ctx: &FormRenderContext<'_, S>,
40        i18n: &FluentLanguageLoader,
41    ) -> Markup {
42        Input::render_input(self.as_deref(), name, title, required, ctx, i18n)
43    }
44}
45
46/// a dynamic reference to an [`Input`] and it's name
47#[derive(Debug)]
48pub struct InputInfo<'a, S: ContextTrait> {
49    /// Used for the `name` field of the HTML form
50    pub name: &'a str,
51    /// the title shown in the UI
52    pub title: &'a str,
53    /// The help text shown in the UI
54    pub help: Option<&'a str>,
55    pub value: Box<dyn DynInput<S> + 'a>,
56}