dioxus_form/
lib.rs

1mod serializer;
2mod deserializer;
3use serde::{ser::Serialize, de::Deserialize};
4use dioxus::prelude::*;
5use serializer::create_form;
6use std::fmt::{Display, Debug};
7
8/// Dioxus Component for automatically creating a html form
9/// Simply pass a Signal into the Component and the Signal will be automatically updated as the
10/// form is updated.
11///
12/// ```rs 
13/// struct FormStruct {
14///     int: i32,
15///     string: String,
16///     b: bool,
17/// }
18///
19/// #[component]
20/// fn App() -> Element {
21///     let signal = use_signal(|| FormStruct { int: 2, string: String::new(), b: true });
22///
23///     rsx! {
24///         Form { value: signal }
25///     }
26/// }
27/// ```
28#[component]
29pub fn Form<T: Clone + Serialize + 'static + PartialEq + for<'de> Deserialize<'de>>(value: Signal<T>) -> Element {
30    let html = use_signal(|| create_form(value));
31
32    rsx! {
33        form {
34            oninput: move |i| {
35                let values = i.values();
36                let result: Result<T, Error> = deserializer::from_values(values); 
37                match result {
38                    Ok(v) => value.set(v),
39                    Err(e) => panic!("{e:?}"),
40                }
41            },
42            dangerous_inner_html: html.read().clone()?,
43        }
44    }
45}
46
47#[derive(Debug, Clone)]
48pub struct Error {
49    _message: String,
50}
51
52impl Display for Error {
53    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { Display::fmt(&self, f) }
54}
55
56impl serde::ser::Error for Error {
57    fn custom<T>(msg: T) -> Self
58    where
59        T: Display,
60    {
61        Error {
62            _message: msg.to_string(),
63        }
64    }
65}
66
67impl serde::de::Error for Error {
68    fn custom<T>(msg: T) -> Self
69    where
70        T: Display,
71    {
72        Error {
73            _message: msg.to_string(),
74        }
75    }
76}
77
78impl serde::ser::StdError for Error {
79    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
80
81    fn description(&self) -> &str { "description() is deprecated; use Display" }
82
83    fn cause(&self) -> Option<&dyn std::error::Error> { self.source() }
84
85    //fn provide<'a>(&'a self, request: &mut std::error::Request<'a>) {}
86}