pub struct Form { /* private fields */ }Expand description
Form data structure (Phase 2-A: Enhanced with client-side validation rules)
Implementations§
Source§impl Form
impl Form
Sourcepub fn new() -> Self
pub fn new() -> Self
Create a new empty form
§Examples
use reinhardt_forms::Form;
let form = Form::new();
assert!(!form.is_bound());
assert!(form.fields().is_empty());Sourcepub fn with_initial(initial: HashMap<String, Value>) -> Self
pub fn with_initial(initial: HashMap<String, Value>) -> Self
Create a new form with initial data
§Examples
use reinhardt_forms::Form;
use std::collections::HashMap;
use serde_json::json;
let mut initial = HashMap::new();
initial.insert("name".to_string(), json!("John"));
let form = Form::with_initial(initial);
assert_eq!(form.initial().get("name"), Some(&json!("John")));Sourcepub fn with_prefix(prefix: String) -> Self
pub fn with_prefix(prefix: String) -> Self
Create a new form with a field prefix
§Examples
use reinhardt_forms::Form;
let form = Form::with_prefix("user".to_string());
assert_eq!(form.prefix(), "user");
assert_eq!(form.add_prefix_to_field_name("email"), "user-email");Sourcepub fn add_field(&mut self, field: Box<dyn FormField>)
pub fn add_field(&mut self, field: Box<dyn FormField>)
Add a field to the form
§Examples
use reinhardt_forms::{Form, CharField, Field};
let mut form = Form::new();
let field = CharField::new("username".to_string());
form.add_field(Box::new(field));
assert_eq!(form.fields().len(), 1);Sourcepub fn bind(&mut self, data: HashMap<String, Value>)
pub fn bind(&mut self, data: HashMap<String, Value>)
Bind form data for validation
§Examples
use reinhardt_forms::Form;
use std::collections::HashMap;
use serde_json::json;
let mut form = Form::new();
let mut data = HashMap::new();
data.insert("username".to_string(), json!("john"));
form.bind(data);
assert!(form.is_bound());Sourcepub fn is_valid(&mut self) -> bool
pub fn is_valid(&mut self) -> bool
Validate the form and return true if all fields are valid
§Examples
use reinhardt_forms::{Form, CharField, Field};
use std::collections::HashMap;
use serde_json::json;
let mut form = Form::new();
form.add_field(Box::new(CharField::new("username".to_string())));
let mut data = HashMap::new();
data.insert("username".to_string(), json!("john"));
form.bind(data);
assert!(form.is_valid());
assert!(form.errors().is_empty());
assert_eq!(form.cleaned_data().get("username"), Some(&json!("john")));pub fn cleaned_data(&self) -> &HashMap<String, Value>
pub fn errors(&self) -> &HashMap<String, Vec<String>>
pub fn is_bound(&self) -> bool
pub fn fields(&self) -> &[Box<dyn FormField>]
pub fn initial(&self) -> &HashMap<String, Value>
Sourcepub fn set_initial(&mut self, initial: HashMap<String, Value>)
pub fn set_initial(&mut self, initial: HashMap<String, Value>)
Set initial data for the form
§Examples
use reinhardt_forms::Form;
use std::collections::HashMap;
use serde_json::json;
let mut form = Form::new();
let mut initial = HashMap::new();
initial.insert("name".to_string(), json!("John"));
form.set_initial(initial);Sourcepub fn has_changed(&self) -> bool
pub fn has_changed(&self) -> bool
Check if any field has changed from its initial value
§Examples
use reinhardt_forms::{Form, CharField, Field};
use std::collections::HashMap;
use serde_json::json;
let mut initial = HashMap::new();
initial.insert("name".to_string(), json!("John"));
let mut form = Form::with_initial(initial);
form.add_field(Box::new(CharField::new("name".to_string())));
let mut data = HashMap::new();
data.insert("name".to_string(), json!("Jane"));
form.bind(data);
assert!(form.has_changed());pub fn get_field(&self, name: &str) -> Option<&dyn FormField>
pub fn remove_field(&mut self, name: &str) -> Option<Box<dyn FormField>>
pub fn field_count(&self) -> usize
Sourcepub fn add_clean_function<F>(&mut self, f: F)
pub fn add_clean_function<F>(&mut self, f: F)
Add a custom clean function for form validation
§Examples
use reinhardt_forms::Form;
use std::collections::HashMap;
use serde_json::json;
let mut form = Form::new();
form.add_clean_function(|data| {
if data.get("password") != data.get("confirm_password") {
Err(reinhardt_forms::FormError::Validation("Passwords do not match".to_string()))
} else {
Ok(())
}
});Sourcepub fn add_field_clean_function<F>(&mut self, field_name: &str, f: F)
pub fn add_field_clean_function<F>(&mut self, field_name: &str, f: F)
Add a custom clean function for a specific field
§Examples
use reinhardt_forms::Form;
use serde_json::json;
let mut form = Form::new();
form.add_field_clean_function("email", |value| {
if let Some(email) = value.as_str() {
if email.contains("@") {
Ok(value.clone())
} else {
Err(reinhardt_forms::FormError::Validation("Invalid email".to_string()))
}
} else {
Ok(value.clone())
}
});Sourcepub fn validation_rules(&self) -> &[ValidationRule]
pub fn validation_rules(&self) -> &[ValidationRule]
Sourcepub fn add_min_length_validator(
&mut self,
field_name: impl Into<String>,
min: usize,
error_message: impl Into<String>,
)
pub fn add_min_length_validator( &mut self, field_name: impl Into<String>, min: usize, error_message: impl Into<String>, )
Add a minimum length validator (Phase 2-A)
Adds a validator that checks if a string field has at least min characters.
This validator is executed on the client-side for immediate feedback.
Security Note: Client-side validation is for UX enhancement only. Server-side validation is still mandatory for security.
§Arguments
field_name: Name of the field to validatemin: Minimum required lengtherror_message: Error message to display on validation failure
§Examples
use reinhardt_forms::Form;
let mut form = Form::new();
form.add_min_length_validator("password", 8, "Password must be at least 8 characters");Sourcepub fn add_max_length_validator(
&mut self,
field_name: impl Into<String>,
max: usize,
error_message: impl Into<String>,
)
pub fn add_max_length_validator( &mut self, field_name: impl Into<String>, max: usize, error_message: impl Into<String>, )
Add a maximum length validator (Phase 2-A)
Adds a validator that checks if a string field has at most max characters.
§Examples
use reinhardt_forms::Form;
let mut form = Form::new();
form.add_max_length_validator("username", 50, "Username must be at most 50 characters");Sourcepub fn add_pattern_validator(
&mut self,
field_name: impl Into<String>,
pattern: impl Into<String>,
error_message: impl Into<String>,
)
pub fn add_pattern_validator( &mut self, field_name: impl Into<String>, pattern: impl Into<String>, error_message: impl Into<String>, )
Add a pattern validator (Phase 2-A)
Adds a validator that checks if a string field matches a regex pattern.
§Examples
use reinhardt_forms::Form;
let mut form = Form::new();
form.add_pattern_validator("code", "^[A-Z]{3}$", "Code must be 3 uppercase letters");Sourcepub fn add_min_value_validator(
&mut self,
field_name: impl Into<String>,
min: f64,
error_message: impl Into<String>,
)
pub fn add_min_value_validator( &mut self, field_name: impl Into<String>, min: f64, error_message: impl Into<String>, )
Add a minimum value validator (Phase 2-A)
Adds a validator that checks if a numeric field is at least min.
§Examples
use reinhardt_forms::Form;
let mut form = Form::new();
form.add_min_value_validator("age", 0.0, "Age must be non-negative");Sourcepub fn add_max_value_validator(
&mut self,
field_name: impl Into<String>,
max: f64,
error_message: impl Into<String>,
)
pub fn add_max_value_validator( &mut self, field_name: impl Into<String>, max: f64, error_message: impl Into<String>, )
Add a maximum value validator (Phase 2-A)
Adds a validator that checks if a numeric field is at most max.
§Examples
use reinhardt_forms::Form;
let mut form = Form::new();
form.add_max_value_validator("age", 150.0, "Age must be at most 150");Sourcepub fn add_email_validator(
&mut self,
field_name: impl Into<String>,
error_message: impl Into<String>,
)
pub fn add_email_validator( &mut self, field_name: impl Into<String>, error_message: impl Into<String>, )
Add an email format validator (Phase 2-A)
Adds a validator that checks if a field contains a valid email format.
§Examples
use reinhardt_forms::Form;
let mut form = Form::new();
form.add_email_validator("email", "Enter a valid email address");Sourcepub fn add_url_validator(
&mut self,
field_name: impl Into<String>,
error_message: impl Into<String>,
)
pub fn add_url_validator( &mut self, field_name: impl Into<String>, error_message: impl Into<String>, )
Add a URL format validator (Phase 2-A)
Adds a validator that checks if a field contains a valid URL format.
§Examples
use reinhardt_forms::Form;
let mut form = Form::new();
form.add_url_validator("website", "Enter a valid URL");Sourcepub fn add_fields_equal_validator(
&mut self,
field_names: Vec<String>,
error_message: impl Into<String>,
target_field: Option<String>,
)
pub fn add_fields_equal_validator( &mut self, field_names: Vec<String>, error_message: impl Into<String>, target_field: Option<String>, )
Add a fields equality validator (Phase 2-A)
Adds a validator that checks if multiple fields have equal values. Commonly used for password confirmation.
§Arguments
field_names: Names of fields to compare for equalityerror_message: Error message to display on validation failuretarget_field: Target field for error display (None = non-field error)
§Examples
use reinhardt_forms::Form;
let mut form = Form::new();
form.add_fields_equal_validator(
vec!["password".to_string(), "password_confirm".to_string()],
"Passwords do not match",
Some("password_confirm".to_string())
);Sourcepub fn add_validator_rule(
&mut self,
field_name: impl Into<String>,
validator_id: impl Into<String>,
params: Value,
error_message: impl Into<String>,
)
pub fn add_validator_rule( &mut self, field_name: impl Into<String>, validator_id: impl Into<String>, params: Value, error_message: impl Into<String>, )
Add a client-side validator reference (Phase 2-A)
Adds a reference to a reinhardt-validators Validator. This validator is executed on the client-side for immediate feedback.
Security Note: Client-side validation is for UX enhancement only. Server-side validation is still mandatory for security.
§Arguments
field_name: Name of the field to validatevalidator_id: Validator identifier (e.g., “email”, “url”, “min_length”)params: Validator parameters as JSONerror_message: Error message to display on validation failure
§Examples
use reinhardt_forms::Form;
use serde_json::json;
let mut form = Form::new();
form.add_validator_rule(
"email",
"email",
json!({}),
"Enter a valid email address"
);
form.add_validator_rule(
"username",
"min_length",
json!({"min": 3}),
"Username must be at least 3 characters"
);Sourcepub fn add_date_range_validator(
&mut self,
start_field: impl Into<String>,
end_field: impl Into<String>,
error_message: Option<String>,
)
pub fn add_date_range_validator( &mut self, start_field: impl Into<String>, end_field: impl Into<String>, error_message: Option<String>, )
Helper: Add a date range validator (Phase 2-A)
Adds a validator that checks if end_date >= start_date.
§Arguments
start_field: Name of the start date fieldend_field: Name of the end date fielderror_message: Error message (optional, defaults to a standard message)
§Examples
use reinhardt_forms::Form;
let mut form = Form::new();
form.add_date_range_validator("start_date", "end_date", None);Sourcepub fn add_numeric_range_validator(
&mut self,
min_field: impl Into<String>,
max_field: impl Into<String>,
error_message: Option<String>,
)
pub fn add_numeric_range_validator( &mut self, min_field: impl Into<String>, max_field: impl Into<String>, error_message: Option<String>, )
Helper: Add a numeric range validator (Phase 2-A)
Adds a validator that checks if max >= min.
§Arguments
min_field: Name of the minimum value fieldmax_field: Name of the maximum value fielderror_message: Error message (optional, defaults to a standard message)
§Examples
use reinhardt_forms::Form;
let mut form = Form::new();
form.add_numeric_range_validator("min_price", "max_price", None);Sourcepub fn set_csrf_token(&mut self, token: String)
pub fn set_csrf_token(&mut self, token: String)
Enable CSRF protection for this form.
When enabled, is_valid() will check that the submitted data
contains a matching CSRF token.
§Arguments
token- The expected CSRF token for this form
§Examples
use reinhardt_forms::Form;
let mut form = Form::new();
form.set_csrf_token("abc123".to_string());
assert!(form.csrf_enabled());Sourcepub fn csrf_enabled(&self) -> bool
pub fn csrf_enabled(&self) -> bool
Check if CSRF protection is enabled
Sourcepub fn csrf_token(&self) -> Option<&str>
pub fn csrf_token(&self) -> Option<&str>
Get the CSRF token, if set
pub fn prefix(&self) -> &str
pub fn set_prefix(&mut self, prefix: String)
pub fn add_prefix_to_field_name(&self, field_name: &str) -> String
Sourcepub fn render_css_media(&self, css_files: &[&str]) -> String
pub fn render_css_media(&self, css_files: &[&str]) -> String
Render CSS <link> tags for form media with HTML-escaped paths.
All paths are escaped using escape_attribute() to prevent XSS
via malicious CSS file paths.
§Arguments
css_files- Slice of CSS file paths to include
§Examples
use reinhardt_forms::Form;
let form = Form::new();
let html = form.render_css_media(&["/static/forms.css"]);
assert!(html.contains("href=\"/static/forms.css\""));Sourcepub fn render_js_media(&self, js_files: &[&str]) -> String
pub fn render_js_media(&self, js_files: &[&str]) -> String
Render JS <script> tags for form media with HTML-escaped paths.
All paths are escaped using escape_attribute() to prevent XSS
via malicious JS file paths.
§Arguments
js_files- Slice of JS file paths to include
§Examples
use reinhardt_forms::Form;
let form = Form::new();
let html = form.render_js_media(&["/static/forms.js"]);
assert!(html.contains("src=\"/static/forms.js\""));pub fn get_bound_field<'a>(&'a self, name: &str) -> Option<BoundField<'a>>
Source§impl Form
Safe field access by name.
impl Form
Safe field access by name.
Returns None if the field is not found instead of panicking.
§Examples
use reinhardt_forms::{Form, CharField, Field};
let mut form = Form::new();
form.add_field(Box::new(CharField::new("name".to_string())));
assert!(form.get("name").is_some());
assert!(form.get("nonexistent").is_none());