github.com/Datadog/cnab-go@v0.3.3-beta1.0.20191007143216-bba4b7e723d0/bundle/definition/validation.go (about) 1 package definition 2 3 import ( 4 "encoding/json" 5 6 "github.com/pkg/errors" 7 ) 8 9 // ValidationError error represents a validation error 10 // against the JSON Schema. The type includes the path 11 // in the given object and the error message 12 type ValidationError struct { 13 Path string 14 Error string 15 } 16 17 // Validate applies JSON Schema validation to the data passed as a parameter. 18 // If validation errors occur, they will be returned in as a slice of ValidationError 19 // structs. If any other error occurs, it will be returned as a separate error 20 func (s *Schema) Validate(data interface{}) ([]ValidationError, error) { 21 22 b, err := json.Marshal(s) 23 if err != nil { 24 return nil, errors.Wrap(err, "unable to load schema") 25 } 26 def := NewRootSchema() 27 err = json.Unmarshal([]byte(b), def) 28 if err != nil { 29 return nil, errors.Wrap(err, "unable to build schema") 30 } 31 payload, err := json.Marshal(data) 32 if err != nil { 33 return nil, errors.Wrap(err, "unable to process data") 34 } 35 valErrs, err := def.ValidateBytes(payload) 36 if err != nil { 37 return nil, errors.Wrap(err, "unable to perform validation") 38 } 39 if len(valErrs) > 0 { 40 valErrors := []ValidationError{} 41 42 for _, err := range valErrs { 43 valError := ValidationError{ 44 Path: err.PropertyPath, 45 Error: err.Message, 46 } 47 valErrors = append(valErrors, valError) 48 } 49 return valErrors, nil 50 } 51 return nil, nil 52 } 53 54 // CoerceValue can be used to turn float and other numeric types into integers. When 55 // unmarshaled, often integer values are not represented as an integer. This is a 56 // convenience method. 57 func (s *Schema) CoerceValue(value interface{}) interface{} { 58 if s.Type == "int" || s.Type == "integer" { 59 f, ok := value.(float64) 60 if ok { 61 i, ok := asInt(f) 62 if !ok { 63 return f 64 } 65 return i 66 } 67 } 68 return value 69 } 70 71 func asInt(f float64) (int, bool) { 72 i := int(f) 73 if float64(i) != f { 74 return 0, false 75 } 76 return i, true 77 }