1mod serializer;
2mod deserializer;
3use serde::{ser::Serialize, de::Deserialize};
4use dioxus::prelude::*;
5use serializer::create_form;
6use std::fmt::{Display, Debug};
7
8#[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 }