Field declaration
Two ways to declare a field — manually via register_fields, or via the #[form] proc macro.
● ● ●
use runique::prelude::*;
#[derive(Serialize, Debug, Clone)]
#[serde(transparent)]
pub struct MyForm {
pub form: Forms,
}
impl RuniqueForm for MyForm {
fn register_fields(form: &mut Forms) {
form.field(&TextField::text("username")
.label("Username"));
form.field(&TextField::email("email")
.label("Email address"));
form.field(&TextField::password("password")
.label("Password")
.min_length(8, "8 characters minimum"));
form.field(&NumericField::integer("age")
.label("Age")
.min(0.0, "Positive value"));
form.field(&BooleanField::new("active")
.label("Active account"));
let roles = vec![
ChoiceOption::new("admin", "Administrator"),
ChoiceOption::new("user", "User"),
];
form.field(&ChoiceField::new("role")
.label("Role")
.choices(roles));
}
}
use crate::entities::contribution::schema as contribution;
use runique::prelude::*;
// Fields are read from the SeaORM schema
// — types, constraints, nullable deduced automatically
#[form(schema = contribution, fields = [title, content])]
pub struct ContributionForm;
#[async_trait]
impl RuniqueForm for ContributionForm {
impl_form_access!(model);
async fn clean(&mut self) -> Result<(), StrMap> {
let title = self.cleaned_string("title").unwrap_or_default();
let mut errors = StrMap::new();
if title.len() < 5 {
errors.insert(
"title".to_string(),
"5 characters minimum".to_string(),
);
}
if errors.is_empty() { Ok(()) }
else { Err(errors) }
}
}
// Manual — full control, no DB entity
// -> ideal for contact forms, login, search
// #[form] — wired to the SeaORM schema
// -> ideal for CRUD, Django-like ModelForm
// -> form.save(&db).await? available automatically