src

Go monorepo.
git clone git://code.dwrz.net/src
Log | Files | Refs

validation.go (3675B)


      1 package smithy
      2 
      3 import (
      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.
     11 type 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.
     20 func (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.
     30 func (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
     39 func (e *InvalidParamsError) Len() int {
     40 	return len(e.errs)
     41 }
     42 
     43 // Error returns the string formatted form of the invalid parameters.
     44 func (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
     56 func (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.
     66 type 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 
     79 type 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.
     87 func (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.
     92 func (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.
    109 func (e *invalidParamError) SetContext(ctx string) {
    110 	e.context = ctx
    111 }
    112 
    113 // AddNestedContext prepends a context to the field's path.
    114 func (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.
    128 type ParamRequiredError struct {
    129 	invalidParamError
    130 }
    131 
    132 // NewErrParamRequired creates a new required parameter error.
    133 func NewErrParamRequired(field string) *ParamRequiredError {
    134 	return &ParamRequiredError{
    135 		invalidParamError{
    136 			field:  field,
    137 			reason: fmt.Sprintf("missing required field"),
    138 		},
    139 	}
    140 }