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>

Source

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

Source

pub fn is_bound(&self) -> bool

Source

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

Source

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

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>

Source

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

Source

pub fn field_count(&self) -> usize

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

Source

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

Source

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

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>>

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>>

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, 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.