// Package web holds small, framework-agnostic helpers shared across HTTP
// handlers — things that don't fit cleanly in `server` (because they have
// no handler-specific state) and shouldn't pull in domain dependencies.
package web
// FieldErrors maps form-field names to human-readable error messages.
//
// Convention per docs/operator-ux-conventions.md §6: every form that mutates
// revalidates server-side and renders field-level errors. Handler builds a
// FieldErrors map during validation; on failure returns 422 with the form
// partial + populated map. Templates render `is-invalid` + `
` per field by looking the field name up in the map.
//
// Templates read it with `{{ index .FieldErrors "field_name" }}`, which
// returns the empty string if the field has no error (`with` and `if`
// branch on that cleanly).
type FieldErrors map[string]string
// New returns an empty FieldErrors map ready to populate.
func New() FieldErrors {
return make(FieldErrors)
}
// Set records an error for one field. Multiple calls with the same field
// keep only the last message — the convention is one concise, actionable
// message per field, not a list.
func (e FieldErrors) Set(field, msg string) {
e[field] = msg
}
// Get returns the error for one field, or empty string if there is none.
func (e FieldErrors) Get(field string) string {
return e[field]
}
// Has reports whether a specific field has an error.
func (e FieldErrors) Has(field string) bool {
_, ok := e[field]
return ok
}
// Any reports whether any field has an error. Use this as the handler's
// branch point: `if errs.Any() { ...return 422... }`.
func (e FieldErrors) Any() bool {
return len(e) > 0
}