egui_form/lib.rs
1#![doc = include_str!("../README.md")]
2#![forbid(unsafe_code)]
3#![warn(missing_docs)]
4
5mod form;
6
7/// To use [garde] with `egui_form`, you need to create a [`garde::GardeReport`] and pass it to the [Form] instance.
8///
9/// Then, when you create a [`FormField`], you pass the field's name as a &str.
10/// For nested fields and arrays, the syntax for the field name looks like this:
11/// `nested.array[0].field`
12///
13/// # Example
14/// ```no_run
15/// # use eframe::NativeOptions;
16/// # use egui::CentralPanel;
17/// #
18/// # use egui_form::{Form, FormField};
19/// # use garde::Validate;
20/// # use egui_form::garde::field_path;
21///
22/// #[derive(Validate, Debug)]
23/// struct Test {
24/// #[garde(length(min = 3, max = 10))]
25/// pub user_name: String,
26/// #[garde(email)]
27/// pub email: String,
28/// #[garde(dive)]
29/// pub nested: Nested,
30/// #[garde(dive)]
31/// pub vec: Vec<Nested>,
32/// }
33///
34/// #[derive(Validate, Debug)]
35/// struct Nested {
36/// #[garde(range(min = 1, max = 10))]
37/// pub test: u64,
38/// }
39///
40/// pub fn form_ui(ui: &mut egui::Ui, test: &mut Test) {
41/// let mut form = Form::new().add_report(egui_form::garde::GardeReport::new(test.validate()));
42///
43/// FormField::new(&mut form, field_path!("user_name"))
44/// .label("User Name")
45/// .ui(ui, egui::TextEdit::singleline(&mut test.user_name));
46/// FormField::new(&mut form, field_path!("email"))
47/// .label("Email")
48/// .ui(ui, egui::TextEdit::singleline(&mut test.email));
49/// FormField::new(&mut form, field_path!("nested", "test"))
50/// .label("Nested Test")
51/// .ui(ui, egui::Slider::new(&mut test.nested.test, 0..=11));
52/// FormField::new(&mut form, field_path!("vec", 0, "test"))
53/// .label("Vec Test")
54/// .ui(
55/// ui,
56/// egui::DragValue::new(&mut test.vec[0].test).clamp_range(0..=11),
57/// );
58///
59/// if let Some(Ok(())) = form.handle_submit(&ui.button("Submit"), ui) {
60/// println!("Form submitted: {:?}", test);
61/// }
62/// }
63/// ```
64#[cfg(feature = "validator_garde")]
65pub mod garde;
66mod validation_report;
67
68mod form_field;
69/// To use [validator] with `egui_form`, you need to create a [`validator::ValidatorReport`] and pass it to the [Form] instance.
70///
71/// Then, when you create a [`FormField`], you pass a slice of [`validator::PathItem`]s.
72/// Usually, you would use the [`field_path`!] macro to create the slice.
73/// For nested fields and arrays, the syntax for the field name looks like this:
74/// `field_path!("nested", "array", 0, "field")`
75///
76/// # Example
77/// ```no_run
78/// # // Taken 1:1 from crates/egui_form/examples/validator.rs
79/// # use eframe::NativeOptions;
80/// # use egui::CentralPanel;
81/// # use egui_form::{Form, FormField};
82/// # use validator::Validate;
83/// # use egui_form::validator::field_path;
84///
85/// #[derive(Validate, Debug)]
86/// struct Test {
87/// #[validate(length(min = 3, max = 10))]
88/// pub user_name: String,
89/// #[validate(email)]
90/// pub email: String,
91/// #[validate(nested)]
92/// pub nested: Nested,
93/// #[validate(nested)]
94/// pub vec: Vec<Nested>,
95/// }
96///
97/// #[derive(Validate, Debug)]
98/// struct Nested {
99/// #[validate(range(
100/// min = 1,
101/// max = 10,
102/// message = "Custom Message: Must be between 1 and 10"
103/// ))]
104/// pub test: u64,
105/// }
106///
107/// fn form_ui(ui: &mut egui::Ui, test: &mut Test) {
108/// let mut form = Form::new().add_report(
109/// egui_form::validator::ValidatorReport::new(test.validate()).with_translation(|error| {
110/// // Since validator doesn't have default messages, we have to provide our own
111/// if let Some(msg) = &error.message {
112/// return msg.clone();
113/// }
114///
115/// match error.code.as_ref() {
116/// "email" => "Invalid email".into(),
117/// "length" => format!(
118/// "Must be between {} and {} characters long",
119/// error.params["min"], error.params["max"]
120/// )
121/// .into(),
122/// _ => format!("Validation Failed: {}", error.code).into(),
123/// }
124/// }),
125/// );
126///
127/// FormField::new(&mut form, field_path!("user_name"))
128/// .label("User Name")
129/// .ui(ui, egui::TextEdit::singleline(&mut test.user_name));
130/// FormField::new(&mut form, field_path!("email"))
131/// .label("Email")
132/// .ui(ui, egui::TextEdit::singleline(&mut test.email));
133/// FormField::new(&mut form, field_path!("nested", "test"))
134/// .label("Nested Test")
135/// .ui(ui, egui::Slider::new(&mut test.nested.test, 0..=11));
136/// FormField::new(&mut form, field_path!("vec", 0, "test"))
137/// .label("Vec Test")
138/// .ui(
139/// ui,
140/// egui::DragValue::new(&mut test.vec[0].test).clamp_range(0..=11),
141/// );
142///
143/// if let Some(Ok(())) = form.handle_submit(&ui.button("Submit"), ui) {
144/// println!("Form submitted: {:?}", test);
145/// }
146/// }
147#[cfg(feature = "validator_validator")]
148pub mod validator;
149
150pub use form::Form;
151pub use form_field::*;
152pub use validation_report::{EguiValidationReport, IntoFieldPath};