github.com/hashicorp/vault/sdk@v0.13.0/database/dbplugin/v5/marshalling.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: MPL-2.0 3 4 package dbplugin 5 6 import ( 7 "encoding/json" 8 "math" 9 10 "google.golang.org/protobuf/types/known/structpb" 11 ) 12 13 func mapToStruct(m map[string]interface{}) (*structpb.Struct, error) { 14 // Convert any json.Number typed values to float64, since the 15 // type does not have a conversion mapping defined in structpb 16 for k, v := range m { 17 if n, ok := v.(json.Number); ok { 18 nf, err := n.Float64() 19 if err != nil { 20 return nil, err 21 } 22 23 m[k] = nf 24 } 25 } 26 27 return structpb.NewStruct(m) 28 } 29 30 func structToMap(strct *structpb.Struct) map[string]interface{} { 31 m := strct.AsMap() 32 coerceFloatsToInt(m) 33 return m 34 } 35 36 // coerceFloatsToInt if the floats can be coerced to an integer without losing data 37 func coerceFloatsToInt(m map[string]interface{}) { 38 for k, v := range m { 39 fVal, ok := v.(float64) 40 if !ok { 41 continue 42 } 43 if isInt(fVal) { 44 m[k] = int64(fVal) 45 } 46 } 47 } 48 49 // isInt attempts to determine if the given floating point number could be represented as an integer without losing data 50 // This does not work for very large floats, however in this usage that's okay since we don't expect numbers that large. 51 func isInt(f float64) bool { 52 return math.Floor(f) == f 53 }