src.elv.sh@v0.21.0-dev.0.20240515223629-06979efb9a2a/pkg/eval/builtin_fn_pred.go (about) 1 package eval 2 3 import ( 4 "src.elv.sh/pkg/eval/errs" 5 "src.elv.sh/pkg/eval/vals" 6 ) 7 8 // Basic predicate commands. 9 10 func init() { 11 addBuiltinFns(map[string]any{ 12 "bool": vals.Bool, 13 "not": not, 14 "is": is, 15 "eq": eq, 16 "not-eq": notEq, 17 "compare": compare, 18 }) 19 } 20 21 func not(v any) bool { 22 return !vals.Bool(v) 23 } 24 25 func is(args ...any) bool { 26 for i := 0; i+1 < len(args); i++ { 27 if args[i] != args[i+1] { 28 return false 29 } 30 } 31 return true 32 } 33 34 func eq(args ...any) bool { 35 for i := 0; i+1 < len(args); i++ { 36 if !vals.Equal(args[i], args[i+1]) { 37 return false 38 } 39 } 40 return true 41 } 42 43 func notEq(a, b any) bool { 44 return !vals.Equal(a, b) 45 } 46 47 // ErrUncomparable is raised by the compare and order commands when inputs contain 48 // uncomparable values. 49 var ErrUncomparable = errs.BadValue{ 50 What: `inputs to "compare" or "order"`, 51 Valid: "comparable values", Actual: "uncomparable values"} 52 53 type compareOptions struct { 54 Total bool 55 } 56 57 func (opts *compareOptions) SetDefaultOptions() {} 58 59 func compare(opts compareOptions, a, b any) (int, error) { 60 var o vals.Ordering 61 if opts.Total { 62 o = vals.CmpTotal(a, b) 63 } else { 64 o = vals.Cmp(a, b) 65 } 66 switch o { 67 case vals.CmpLess: 68 return -1, nil 69 case vals.CmpEqual: 70 return 0, nil 71 case vals.CmpMore: 72 return 1, nil 73 default: 74 return 0, ErrUncomparable 75 } 76 }