validation.go

  1package smithy
  2
  3import (
  4	"bytes"
  5	"fmt"
  6	"strings"
  7)
  8
  9// An InvalidParamsError provides wrapping of invalid parameter errors found when
 10// validating API operation input parameters.
 11type InvalidParamsError struct {
 12	// Context is the base context of the invalid parameter group.
 13	Context string
 14	errs    []InvalidParamError
 15}
 16
 17// Add adds a new invalid parameter error to the collection of invalid
 18// parameters. The context of the invalid parameter will be updated to reflect
 19// this collection.
 20func (e *InvalidParamsError) Add(err InvalidParamError) {
 21	err.SetContext(e.Context)
 22	e.errs = append(e.errs, err)
 23}
 24
 25// AddNested adds the invalid parameter errors from another InvalidParamsError
 26// value into this collection. The nested errors will have their nested context
 27// updated and base context to reflect the merging.
 28//
 29// Use for nested validations errors.
 30func (e *InvalidParamsError) AddNested(nestedCtx string, nested InvalidParamsError) {
 31	for _, err := range nested.errs {
 32		err.SetContext(e.Context)
 33		err.AddNestedContext(nestedCtx)
 34		e.errs = append(e.errs, err)
 35	}
 36}
 37
 38// Len returns the number of invalid parameter errors
 39func (e *InvalidParamsError) Len() int {
 40	return len(e.errs)
 41}
 42
 43// Error returns the string formatted form of the invalid parameters.
 44func (e InvalidParamsError) Error() string {
 45	w := &bytes.Buffer{}
 46	fmt.Fprintf(w, "%d validation error(s) found.\n", len(e.errs))
 47
 48	for _, err := range e.errs {
 49		fmt.Fprintf(w, "- %s\n", err.Error())
 50	}
 51
 52	return w.String()
 53}
 54
 55// Errs returns a slice of the invalid parameters
 56func (e InvalidParamsError) Errs() []error {
 57	errs := make([]error, len(e.errs))
 58	for i := 0; i < len(errs); i++ {
 59		errs[i] = e.errs[i]
 60	}
 61
 62	return errs
 63}
 64
 65// An InvalidParamError represents an invalid parameter error type.
 66type InvalidParamError interface {
 67	error
 68
 69	// Field name the error occurred on.
 70	Field() string
 71
 72	// SetContext updates the context of the error.
 73	SetContext(string)
 74
 75	// AddNestedContext updates the error's context to include a nested level.
 76	AddNestedContext(string)
 77}
 78
 79type invalidParamError struct {
 80	context       string
 81	nestedContext string
 82	field         string
 83	reason        string
 84}
 85
 86// Error returns the string version of the invalid parameter error.
 87func (e invalidParamError) Error() string {
 88	return fmt.Sprintf("%s, %s.", e.reason, e.Field())
 89}
 90
 91// Field Returns the field and context the error occurred.
 92func (e invalidParamError) Field() string {
 93	sb := &strings.Builder{}
 94	sb.WriteString(e.context)
 95	if sb.Len() > 0 {
 96		if len(e.nestedContext) == 0 || (len(e.nestedContext) > 0 && e.nestedContext[:1] != "[") {
 97			sb.WriteRune('.')
 98		}
 99	}
100	if len(e.nestedContext) > 0 {
101		sb.WriteString(e.nestedContext)
102		sb.WriteRune('.')
103	}
104	sb.WriteString(e.field)
105	return sb.String()
106}
107
108// SetContext updates the base context of the error.
109func (e *invalidParamError) SetContext(ctx string) {
110	e.context = ctx
111}
112
113// AddNestedContext prepends a context to the field's path.
114func (e *invalidParamError) AddNestedContext(ctx string) {
115	if len(e.nestedContext) == 0 {
116		e.nestedContext = ctx
117		return
118	}
119	// Check if our nested context is an index into a slice or map
120	if e.nestedContext[:1] != "[" {
121		e.nestedContext = fmt.Sprintf("%s.%s", ctx, e.nestedContext)
122		return
123	}
124	e.nestedContext = ctx + e.nestedContext
125}
126
127// An ParamRequiredError represents an required parameter error.
128type ParamRequiredError struct {
129	invalidParamError
130}
131
132// NewErrParamRequired creates a new required parameter error.
133func NewErrParamRequired(field string) *ParamRequiredError {
134	return &ParamRequiredError{
135		invalidParamError{
136			field:  field,
137			reason: fmt.Sprintf("missing required field"),
138		},
139	}
140}