Skip to content

Commit 6e9b9fc

Browse files
author
Paddy Carver
committed
Make all Numbers *big.Floats by default.
When handling types that came from JSON or msgpack, anything that's supposed to be a number we try to coerce into being a *big.Float, which is the only lossless type we can standardise all Numbers on. This prevents developers from needing to worry about getting Numbers in different intermediary types based on what value was provided. Unmarshal will give developers the type in whatever convenient format they ask for, but will always throw an error in the face of a loss of specificity (except for float32/float64, in which case it's impossible to know if accuracy was lost).
1 parent 422b678 commit 6e9b9fc

File tree

1 file changed

+34
-9
lines changed

1 file changed

+34
-9
lines changed

tfprotov5/tftypes/raw_value.go

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -333,15 +333,40 @@ func unmarshalFloat64(in float64, dst interface{}) error {
333333
func rawValueFromComplexType(typ Type, val interface{}) (RawValue, error) {
334334
if _, ok := typ.(primitive); ok {
335335
if typ.Is(Number) {
336-
// TODO: put numbers in a consistent format
337-
// numbers could be coming to us as like a billion
338-
// different types, and we want developers to have
339-
// stable types to build against. We should cast or
340-
// wrap as necessary here to handle that.
341-
return RawValue{
342-
Type: Number,
343-
Value: val,
344-
}, nil
336+
result := RawValue{
337+
Type: Number,
338+
}
339+
switch v := val.(type) {
340+
case *big.Float:
341+
v.Set(v)
342+
case uint64:
343+
result.Value = big.NewFloat(float64(v))
344+
case uint32:
345+
result.Value = big.NewFloat(float64(v))
346+
case uint16:
347+
result.Value = big.NewFloat(float64(v))
348+
case uint8:
349+
result.Value = big.NewFloat(float64(v))
350+
case uint:
351+
result.Value = big.NewFloat(float64(v))
352+
case int64:
353+
result.Value = big.NewFloat(float64(v))
354+
case int32:
355+
result.Value = big.NewFloat(float64(v))
356+
case int16:
357+
result.Value = big.NewFloat(float64(v))
358+
case int8:
359+
result.Value = big.NewFloat(float64(v))
360+
case int:
361+
result.Value = big.NewFloat(float64(v))
362+
case float64:
363+
result.Value = big.NewFloat(v)
364+
case float32:
365+
result.Value = big.NewFloat(float64(v))
366+
default:
367+
return result, fmt.Errorf("can't use type %T as a %s", val, Number)
368+
}
369+
return result, nil
345370
}
346371
return RawValue{
347372
Type: typ,

0 commit comments

Comments
 (0)