Aria's validation system is reactive-first: validators bind to Property<T> and automatically re-evaluate when the value changes. Results are exposed as Property<ValidationState> — bind them to your UI like any other reactive value.
Include: #include "aria/validator.hpp"
Validator<T>
Attaches validation rules to a Property<T>. Re-runs all rules whenever the source changes.
Basic: Required Field
email_valid.
must([](
const std::string& v) {
return !v.empty(); },
"Email is required", "required");
}
});
Definition validator.hpp:135
Property< ValidationState > & state() noexcept
Definition validator.hpp:312
Validator & must(P &&predicate, std::string message, std::string rule_id_value={})
Definition validator.hpp:184
Definition property.hpp:103
Definition validator.hpp:61
std::optional< std::string > first_error_message() const
First Error-severity message text, if any.
Definition validator.hpp:93
bool valid
True iff there are no Error-severity entries.
Definition validator.hpp:64
Multiple Rules
email_valid
.
must([](
const std::string& v) {
return !v.empty(); },
"Email is required", "required")
.must([](const std::string& v) { return v.contains('@'); },
"Must contain @", "at_sign")
.must([](const std::string& v) { return v.size() >= 5; },
"Too short", "min_length");
Rules are evaluated in order. All failing rules contribute errors — the user sees every problem at once.
Warnings (Soft Advisories)
Warnings do NOT make the field invalid:
email_valid.
should([](
const std::string& v) {
return !v.ends_with(
".co"); },
".co domains may have issues", "dot_co_warning");
Validator & should(P &&predicate, std::string message, std::string rule_id_value={})
Definition validator.hpp:206
Custom Rule Function
Full control — return std::optional<std::string> (message on failure, nullopt on pass):
email_valid.
rule([](
const std::string& v) -> std::optional<std::string> {
if (v.find("..") != std::string::npos)
return "Consecutive dots are not allowed";
return std::nullopt;
}, "no_double_dots");
Validator & rule(Rule r, std::string rule_id_value={})
Definition validator.hpp:173
Bulk Rules
Add multiple rules without triggering intermediate evaluations:
[](const std::string& v) -> std::optional<std::string> {
return v.empty() ? std::optional{"Required"} : std::nullopt;
},
[](const std::string& v) -> std::optional<std::string> {
return !v.contains('@') ? std::optional{"Need @"} : std::nullopt;
}
});
Validator & rules(std::initializer_list< Rule > rs)
Definition validator.hpp:217
ValidationState
The rich form-state record exposed by validator.state():
| Field | Type | Meaning |
| valid | bool | True if no Error-severity entries |
| pending | bool | True while async validation is running |
| touched | bool | True after user interaction (focus-out) |
| dirty | bool | True if value differs from baseline |
| errors | vector<Error> | Hard failures |
| warnings | vector<Error> | Soft advisories |
Convenience Queries
auto& s = validator.state().get();
std::optional< Error > first_error() const
First Error-severity entry, if any.
Definition validator.hpp:87
std::vector< Error > errors_for(std::string_view field_path) const
All Error-severity entries that target a given field path.
Definition validator.hpp:100
bool has_error_with_rule(std::string_view rule_id) const noexcept
True if any Error-severity entry has the given rule_id.
Definition validator.hpp:109
Form-State Transitions
Touch
Mark a field as user-interacted (typically on blur):
void touch()
Definition validator.hpp:230
Reset Dirty
Snap the baseline to the current value (e.g. after a successful save):
void reset_dirty()
Definition validator.hpp:244
Reset Touched
Clear the touched flag (e.g. when resetting a form):
void reset_touched()
Definition validator.hpp:237
Async Validation
For rules that need server-side checks (username availability, etc.):
username_valid.
must([](
const std::string& v) {
return v.size() >= 3; },
"At least 3 characters", "min_length");
void begin_pending()
Definition validator.hpp:256
void end_pending(std::vector< std::string > extra_messages)
Settle the async validation: clears pending and stores extra_messages as additional Error-severity en...
Definition validator.hpp:276
ValidationResult (Legacy)
A simpler projection with just valid + errors. Available via validator.result():
auto& r = email_valid.
result().get();
r.valid;
r.errors;
r.error_messages();
Property< ValidationResult > & result() noexcept
Definition validator.hpp:315
New code should prefer state() — it includes pending, touched, and dirty.
FormValidator
Compose multiple validators into a form-level validity check:
form.add(email_valid);
form.add(password_valid);
form.add(age_valid);
});
bool pending
True while an async validator is running.
Definition validator.hpp:67
Quick Reference
| Method | Description |
| Validator(prop, field_path) | Attach to a Property |
| .rule(fn, id) | Add custom rule |
| .must(pred, msg, id) | Add predicate rule (error) |
| .should(pred, msg, id) | Add predicate rule (warning) |
| .rules({...}) | Bulk-add rules |
| .touch() | Mark as user-interacted |
| .reset_touched() | Clear touched flag |
| .reset_dirty() | Snap baseline to current |
| .begin_pending() | Enter async-validation state |
| .end_pending(msgs) | Exit pending, add async errors |
| .state() | Property<ValidationState>& |
| .result() | Property<ValidationResult>& |
See Also