Skip to main content

Form

Struct Form 

Source
pub struct Form { /* private fields */ }
Expand description

Form data structure (Phase 2-A: Enhanced with client-side validation rules)

Implementations§

Source§

impl Form

Source

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());
Source

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")));
Source

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");
Source

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);
Source

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());
Source

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")));
Source

pub fn cleaned_data(&self) -> &HashMap<String, Value>

Returns the cleaned (validated) form data.

Source

pub fn errors(&self) -> &HashMap<String, Vec<String>>

Returns the current validation errors keyed by field name.

Source

pub fn add_error( &mut self, field_name: impl Into<String>, message: impl Into<String>, )

Append an error message to the given field’s error list.

Use ALL_FIELDS_KEY for non-field (form-wide / cross-field) errors so they are exposed through the same inspection API as per-field errors.

Source

pub fn is_bound(&self) -> bool

Returns whether the form has been bound with submitted data.

Source

pub fn fields(&self) -> &[Box<dyn FormField>]

Returns the list of fields registered on this form.

Source

pub fn initial(&self) -> &HashMap<String, Value>

Returns the initial (default) values for the form.

Source

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);
Source

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());
Source

pub fn get_field(&self, name: &str) -> Option<&dyn FormField>

Looks up a field by name, returning a reference if found.

Source

pub fn remove_field(&mut self, name: &str) -> Option<Box<dyn FormField>>

Removes and returns a field by name, or None if not found.

Source

pub fn field_count(&self) -> usize

Returns the number of fields registered on this form.

Source

pub fn add_clean_function<F>(&mut self, f: F)
where F: Fn(&HashMap<String, Value>) -> FormResult<()> + Send + Sync + 'static,

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(())
    }
});
Source

pub fn add_field_clean_function<F>(&mut self, field_name: &str, f: F)
where F: Fn(&Value) -> FormResult<Value> + Send + Sync + 'static,

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())
    }
});
Source

pub fn validation_rules(&self) -> &[ValidationRule]

Get client-side validation rules (Phase 2-A)

§Returns

Reference to the validation rules vector

Source

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 validate
  • min: Minimum required length
  • error_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");
Source

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");
Source

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");
Source

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");
Source

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");
Source

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");
Source

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");
Source

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 equality
  • error_message: Error message to display on validation failure
  • target_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())
);
Source

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 validate
  • validator_id: Validator identifier (e.g., “email”, “url”, “min_length”)
  • params: Validator parameters as JSON
  • error_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"
);
Source

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 field
  • end_field: Name of the end date field
  • error_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);
Source

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 field
  • max_field: Name of the maximum value field
  • error_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);
Source

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());
Source

pub fn csrf_enabled(&self) -> bool

Check if CSRF protection is enabled

Source

pub fn csrf_token(&self) -> Option<&str>

Get the CSRF token, if set

Source

pub fn prefix(&self) -> &str

Returns the field name prefix for this form.

Source

pub fn set_prefix(&mut self, prefix: String)

Sets the field name prefix for this form.

Source

pub fn add_prefix_to_field_name(&self, field_name: &str) -> String

Returns the field name with the form prefix prepended (e.g., “prefix-field”).

Source

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\""));
Source

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\""));
Source

pub fn get_bound_field<'a>(&'a self, name: &str) -> Option<BoundField<'a>>

Returns a BoundField with the field’s submitted data and errors attached.

Source§

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());
Source

pub fn get(&self, name: &str) -> Option<&Box<dyn FormField>>

Looks up a field by name, returning a reference to the boxed field.

Trait Implementations§

Source§

impl Default for Form

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl FormExt for Form

Source§

fn to_metadata(&self) -> FormMetadata

Extract serializable metadata from the form Read more
Source§

impl Index<&str> for Form

Source§

type Output = Box<dyn FormField>

The returned type after indexing.
Source§

fn index(&self, name: &str) -> &Self::Output

Performs the indexing (container[index]) operation. Read more

Auto Trait Implementations§

§

impl Freeze for Form

§

impl !RefUnwindSafe for Form

§

impl Send for Form

§

impl Sync for Form

§

impl Unpin for Form

§

impl UnsafeUnpin for Form

§

impl !UnwindSafe for Form

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.