github.com/graywolf-at-work-2/terraform-vendor@v1.4.5/internal/lang/funcs/number.go (about) 1 package funcs 2 3 import ( 4 "math" 5 "math/big" 6 7 "github.com/zclconf/go-cty/cty" 8 "github.com/zclconf/go-cty/cty/function" 9 "github.com/zclconf/go-cty/cty/gocty" 10 ) 11 12 // LogFunc contructs a function that returns the logarithm of a given number in a given base. 13 var LogFunc = function.New(&function.Spec{ 14 Params: []function.Parameter{ 15 { 16 Name: "num", 17 Type: cty.Number, 18 }, 19 { 20 Name: "base", 21 Type: cty.Number, 22 }, 23 }, 24 Type: function.StaticReturnType(cty.Number), 25 Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) { 26 var num float64 27 if err := gocty.FromCtyValue(args[0], &num); err != nil { 28 return cty.UnknownVal(cty.String), err 29 } 30 31 var base float64 32 if err := gocty.FromCtyValue(args[1], &base); err != nil { 33 return cty.UnknownVal(cty.String), err 34 } 35 36 return cty.NumberFloatVal(math.Log(num) / math.Log(base)), nil 37 }, 38 }) 39 40 // PowFunc contructs a function that returns the logarithm of a given number in a given base. 41 var PowFunc = function.New(&function.Spec{ 42 Params: []function.Parameter{ 43 { 44 Name: "num", 45 Type: cty.Number, 46 }, 47 { 48 Name: "power", 49 Type: cty.Number, 50 }, 51 }, 52 Type: function.StaticReturnType(cty.Number), 53 Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) { 54 var num float64 55 if err := gocty.FromCtyValue(args[0], &num); err != nil { 56 return cty.UnknownVal(cty.String), err 57 } 58 59 var power float64 60 if err := gocty.FromCtyValue(args[1], &power); err != nil { 61 return cty.UnknownVal(cty.String), err 62 } 63 64 return cty.NumberFloatVal(math.Pow(num, power)), nil 65 }, 66 }) 67 68 // SignumFunc contructs a function that returns the closest whole number greater 69 // than or equal to the given value. 70 var SignumFunc = function.New(&function.Spec{ 71 Params: []function.Parameter{ 72 { 73 Name: "num", 74 Type: cty.Number, 75 }, 76 }, 77 Type: function.StaticReturnType(cty.Number), 78 Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) { 79 var num int 80 if err := gocty.FromCtyValue(args[0], &num); err != nil { 81 return cty.UnknownVal(cty.String), err 82 } 83 switch { 84 case num < 0: 85 return cty.NumberIntVal(-1), nil 86 case num > 0: 87 return cty.NumberIntVal(+1), nil 88 default: 89 return cty.NumberIntVal(0), nil 90 } 91 }, 92 }) 93 94 // ParseIntFunc contructs a function that parses a string argument and returns an integer of the specified base. 95 var ParseIntFunc = function.New(&function.Spec{ 96 Params: []function.Parameter{ 97 { 98 Name: "number", 99 Type: cty.DynamicPseudoType, 100 AllowMarked: true, 101 }, 102 { 103 Name: "base", 104 Type: cty.Number, 105 AllowMarked: true, 106 }, 107 }, 108 109 Type: func(args []cty.Value) (cty.Type, error) { 110 if !args[0].Type().Equals(cty.String) { 111 return cty.Number, function.NewArgErrorf(0, "first argument must be a string, not %s", args[0].Type().FriendlyName()) 112 } 113 return cty.Number, nil 114 }, 115 116 Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) { 117 var numstr string 118 var base int 119 var err error 120 121 numArg, numMarks := args[0].Unmark() 122 if err = gocty.FromCtyValue(numArg, &numstr); err != nil { 123 return cty.UnknownVal(cty.String), function.NewArgError(0, err) 124 } 125 126 baseArg, baseMarks := args[1].Unmark() 127 if err = gocty.FromCtyValue(baseArg, &base); err != nil { 128 return cty.UnknownVal(cty.Number), function.NewArgError(1, err) 129 } 130 131 if base < 2 || base > 62 { 132 return cty.UnknownVal(cty.Number), function.NewArgErrorf( 133 1, 134 "base must be a whole number between 2 and 62 inclusive", 135 ) 136 } 137 138 num, ok := (&big.Int{}).SetString(numstr, base) 139 if !ok { 140 return cty.UnknownVal(cty.Number), function.NewArgErrorf( 141 0, 142 "cannot parse %s as a base %s integer", 143 redactIfSensitive(numstr, numMarks), 144 redactIfSensitive(base, baseMarks), 145 ) 146 } 147 148 parsedNum := cty.NumberVal((&big.Float{}).SetInt(num)).WithMarks(numMarks, baseMarks) 149 150 return parsedNum, nil 151 }, 152 }) 153 154 // Log returns returns the logarithm of a given number in a given base. 155 func Log(num, base cty.Value) (cty.Value, error) { 156 return LogFunc.Call([]cty.Value{num, base}) 157 } 158 159 // Pow returns the logarithm of a given number in a given base. 160 func Pow(num, power cty.Value) (cty.Value, error) { 161 return PowFunc.Call([]cty.Value{num, power}) 162 } 163 164 // Signum determines the sign of a number, returning a number between -1 and 165 // 1 to represent the sign. 166 func Signum(num cty.Value) (cty.Value, error) { 167 return SignumFunc.Call([]cty.Value{num}) 168 } 169 170 // ParseInt parses a string argument and returns an integer of the specified base. 171 func ParseInt(num cty.Value, base cty.Value) (cty.Value, error) { 172 return ParseIntFunc.Call([]cty.Value{num, base}) 173 }