k8s.io/kube-openapi@v0.0.0-20240228011516-70dd3763d340/pkg/validation/validate/slice_validator.go (about) 1 // Copyright 2015 go-swagger maintainers 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package validate 16 17 import ( 18 "fmt" 19 "reflect" 20 21 "k8s.io/kube-openapi/pkg/validation/spec" 22 "k8s.io/kube-openapi/pkg/validation/strfmt" 23 ) 24 25 type schemaSliceValidator struct { 26 Path string 27 In string 28 MaxItems *int64 29 MinItems *int64 30 UniqueItems bool 31 AdditionalItems *spec.SchemaOrBool 32 Items *spec.SchemaOrArray 33 Root interface{} 34 KnownFormats strfmt.Registry 35 Options SchemaValidatorOptions 36 } 37 38 func (s *schemaSliceValidator) SetPath(path string) { 39 s.Path = path 40 } 41 42 func (s *schemaSliceValidator) Applies(source interface{}, kind reflect.Kind) bool { 43 _, ok := source.(*spec.Schema) 44 r := ok && kind == reflect.Slice 45 return r 46 } 47 48 func (s *schemaSliceValidator) Validate(data interface{}) *Result { 49 result := new(Result) 50 if data == nil { 51 return result 52 } 53 val := reflect.ValueOf(data) 54 size := val.Len() 55 56 if s.Items != nil && s.Items.Schema != nil { 57 for i := 0; i < size; i++ { 58 validator := s.Options.NewValidatorForIndex(i, s.Items.Schema, s.Root, fmt.Sprintf("%s[%d]", s.Path, i), s.KnownFormats, s.Options.Options()...) 59 value := val.Index(i) 60 result.Merge(validator.Validate(value.Interface())) 61 } 62 } 63 64 itemsSize := 0 65 if s.Items != nil && len(s.Items.Schemas) > 0 { 66 itemsSize = len(s.Items.Schemas) 67 for i := 0; i < itemsSize; i++ { 68 validator := s.Options.NewValidatorForIndex(i, &s.Items.Schemas[i], s.Root, fmt.Sprintf("%s[%d]", s.Path, i), s.KnownFormats, s.Options.Options()...) 69 if val.Len() <= i { 70 break 71 } 72 result.Merge(validator.Validate(val.Index(i).Interface())) 73 } 74 } 75 if s.AdditionalItems != nil && itemsSize < size { 76 if s.Items != nil && len(s.Items.Schemas) > 0 && !s.AdditionalItems.Allows { 77 result.AddErrors(arrayDoesNotAllowAdditionalItemsMsg()) 78 } 79 if s.AdditionalItems.Schema != nil { 80 for i := itemsSize; i < size-itemsSize+1; i++ { 81 validator := s.Options.NewValidatorForIndex(i, s.AdditionalItems.Schema, s.Root, fmt.Sprintf("%s[%d]", s.Path, i), s.KnownFormats, s.Options.Options()...) 82 result.Merge(validator.Validate(val.Index(i).Interface())) 83 } 84 } 85 } 86 87 if s.MinItems != nil { 88 if err := MinItems(s.Path, s.In, int64(size), *s.MinItems); err != nil { 89 result.AddErrors(err) 90 } 91 } 92 if s.MaxItems != nil { 93 if err := MaxItems(s.Path, s.In, int64(size), *s.MaxItems); err != nil { 94 result.AddErrors(err) 95 } 96 } 97 if s.UniqueItems { 98 if err := UniqueItems(s.Path, s.In, val.Interface()); err != nil { 99 result.AddErrors(err) 100 } 101 } 102 result.Inc() 103 return result 104 }