github.com/hugorut/terraform@v1.1.3/src/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 }, 101 { 102 Name: "base", 103 Type: cty.Number, 104 }, 105 }, 106 107 Type: func(args []cty.Value) (cty.Type, error) { 108 if !args[0].Type().Equals(cty.String) { 109 return cty.Number, function.NewArgErrorf(0, "first argument must be a string, not %s", args[0].Type().FriendlyName()) 110 } 111 return cty.Number, nil 112 }, 113 114 Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) { 115 var numstr string 116 var base int 117 var err error 118 119 if err = gocty.FromCtyValue(args[0], &numstr); err != nil { 120 return cty.UnknownVal(cty.String), function.NewArgError(0, err) 121 } 122 123 if err = gocty.FromCtyValue(args[1], &base); err != nil { 124 return cty.UnknownVal(cty.Number), function.NewArgError(1, err) 125 } 126 127 if base < 2 || base > 62 { 128 return cty.UnknownVal(cty.Number), function.NewArgErrorf( 129 1, 130 "base must be a whole number between 2 and 62 inclusive", 131 ) 132 } 133 134 num, ok := (&big.Int{}).SetString(numstr, base) 135 if !ok { 136 return cty.UnknownVal(cty.Number), function.NewArgErrorf( 137 0, 138 "cannot parse %q as a base %d integer", 139 numstr, 140 base, 141 ) 142 } 143 144 parsedNum := cty.NumberVal((&big.Float{}).SetInt(num)) 145 146 return parsedNum, nil 147 }, 148 }) 149 150 // Log returns returns the logarithm of a given number in a given base. 151 func Log(num, base cty.Value) (cty.Value, error) { 152 return LogFunc.Call([]cty.Value{num, base}) 153 } 154 155 // Pow returns the logarithm of a given number in a given base. 156 func Pow(num, power cty.Value) (cty.Value, error) { 157 return PowFunc.Call([]cty.Value{num, power}) 158 } 159 160 // Signum determines the sign of a number, returning a number between -1 and 161 // 1 to represent the sign. 162 func Signum(num cty.Value) (cty.Value, error) { 163 return SignumFunc.Call([]cty.Value{num}) 164 } 165 166 // ParseInt parses a string argument and returns an integer of the specified base. 167 func ParseInt(num cty.Value, base cty.Value) (cty.Value, error) { 168 return ParseIntFunc.Call([]cty.Value{num, base}) 169 }