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  }