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  }