cuelang.org/go@v0.10.1/encoding/jsonschema/constraints_array.go (about) 1 // Copyright 2019 CUE Authors 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 jsonschema 16 17 import ( 18 "cuelang.org/go/cue" 19 "cuelang.org/go/cue/ast" 20 "cuelang.org/go/cue/token" 21 ) 22 23 // Array constraints 24 25 func constraintAdditionalItems(key string, n cue.Value, s *state) { 26 switch n.Kind() { 27 case cue.BoolKind: 28 // TODO: support 29 30 case cue.StructKind: 31 if s.list != nil { 32 elem := s.schema(n) 33 s.list.Elts = append(s.list.Elts, &ast.Ellipsis{Type: elem}) 34 } 35 36 default: 37 s.errf(n, `value of "additionalItems" must be an object or boolean`) 38 } 39 } 40 41 func constraintContains(key string, n cue.Value, s *state) { 42 list := s.addImport(n, "list") 43 // TODO: Passing non-concrete values is not yet supported in CUE. 44 if x := s.schema(n); !isAny(x) { 45 x := ast.NewCall(ast.NewSel(list, "Contains"), clearPos(x)) 46 s.add(n, arrayType, x) 47 } 48 } 49 50 func constraintItems(key string, n cue.Value, s *state) { 51 switch n.Kind() { 52 case cue.StructKind: 53 elem := s.schema(n) 54 ast.SetRelPos(elem, token.NoRelPos) 55 s.add(n, arrayType, ast.NewList(&ast.Ellipsis{Type: elem})) 56 57 case cue.ListKind: 58 var a []ast.Expr 59 for _, n := range s.listItems("items", n, true) { 60 v := s.schema(n) // TODO: label with number literal. 61 ast.SetRelPos(v, token.NoRelPos) 62 a = append(a, v) 63 } 64 s.list = ast.NewList(a...) 65 s.add(n, arrayType, s.list) 66 67 default: 68 s.errf(n, `value of "items" must be an object or array`) 69 } 70 } 71 72 func constraintMaxItems(key string, n cue.Value, s *state) { 73 list := s.addImport(n, "list") 74 x := ast.NewCall(ast.NewSel(list, "MaxItems"), clearPos(s.uint(n))) 75 s.add(n, arrayType, x) 76 } 77 78 func constraintMinItems(key string, n cue.Value, s *state) { 79 a := []ast.Expr{} 80 p, err := n.Uint64() 81 if err != nil { 82 s.errf(n, "invalid uint") 83 } 84 for ; p > 0; p-- { 85 a = append(a, ast.NewIdent("_")) 86 } 87 s.add(n, arrayType, ast.NewList(append(a, &ast.Ellipsis{})...)) 88 89 // TODO: use this once constraint resolution is properly implemented. 90 // list := s.addImport(n, "list") 91 // s.addConjunct(n, ast.NewCall(ast.NewSel(list, "MinItems"), clearPos(s.uint(n)))) 92 } 93 94 func constraintUniqueItems(key string, n cue.Value, s *state) { 95 if s.boolValue(n) { 96 list := s.addImport(n, "list") 97 s.add(n, arrayType, ast.NewCall(ast.NewSel(list, "UniqueItems"))) 98 } 99 } 100 101 func clearPos(e ast.Expr) ast.Expr { 102 ast.SetRelPos(e, token.NoRelPos) 103 return e 104 }