package webutil import ( "errors" "fmt" "net/url" ) var ErrUnsupportedType = errors.New("unsupported type") // FormScanFunc is a custom form scanner that can be used to scan custom // types using the form scanner. // // It returns true if it recognizes the type of val, and an error if scanning // fails. type FormScanFunc func(form url.Values, name string, val any) (bool, error) type FormScanner struct { form url.Values err error ScanFunc FormScanFunc } func NewFormScanner(form url.Values) *FormScanner { return &FormScanner{form: form} } func (s *FormScanner) Scan(name string, val any) *FormScanner { if s.err != nil { return s } if s.ScanFunc != nil { if ok, err := s.ScanFunc(s.form, name, val); ok { s.err = err return s } } switch v := val.(type) { case *bool: *v = s.form.Has(name) default: if err := scan(s.form.Get(name), v); err != nil { s.err = fmt.Errorf("Error in field %s: %w", name, err) } } return s } func (s *FormScanner) Error() error { return s.err }