github.com/vmware/govmomi@v0.51.0/vim25/types/json.go (about) 1 // © Broadcom. All Rights Reserved. 2 // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 // SPDX-License-Identifier: Apache-2.0 4 5 package types 6 7 import ( 8 "bytes" 9 "io" 10 "reflect" 11 "time" 12 13 "github.com/vmware/govmomi/vim25/json" 14 ) 15 16 const ( 17 discriminatorMemberName = "_typeName" 18 primitiveValueMemberName = "_value" 19 ) 20 21 var discriminatorTypeRegistry = map[string]reflect.Type{ 22 "boolean": reflect.TypeOf(true), 23 "byte": reflect.TypeOf(uint8(0)), 24 "short": reflect.TypeOf(int16(0)), 25 "int": reflect.TypeOf(int32(0)), 26 "long": reflect.TypeOf(int64(0)), 27 "float": reflect.TypeOf(float32(0)), 28 "double": reflect.TypeOf(float64(0)), 29 "string": reflect.TypeOf(""), 30 "binary": reflect.TypeOf([]byte{}), 31 "dateTime": reflect.TypeOf(time.Now()), 32 } 33 34 // NewJSONDecoder creates JSON decoder configured for VMOMI. 35 func NewJSONDecoder(r io.Reader) *json.Decoder { 36 res := json.NewDecoder(r) 37 res.SetDiscriminator( 38 discriminatorMemberName, 39 primitiveValueMemberName, 40 json.DiscriminatorToTypeFunc(func(name string) (reflect.Type, bool) { 41 if res, ok := TypeFunc()(name); ok { 42 return res, true 43 } 44 if res, ok := discriminatorTypeRegistry[name]; ok { 45 return res, true 46 } 47 return nil, false 48 }), 49 ) 50 return res 51 } 52 53 // VMOMI primitive names 54 var discriminatorNamesRegistry = map[reflect.Type]string{ 55 reflect.TypeOf(true): "boolean", 56 reflect.TypeOf(uint8(0)): "byte", 57 reflect.TypeOf(int16(0)): "short", 58 reflect.TypeOf(int32(0)): "int", 59 reflect.TypeOf(int64(0)): "long", 60 reflect.TypeOf(float32(0)): "float", 61 reflect.TypeOf(float64(0)): "double", 62 reflect.TypeOf(""): "string", 63 reflect.TypeOf([]byte{}): "binary", 64 reflect.TypeOf(time.Now()): "dateTime", 65 } 66 67 // NewJSONEncoder creates JSON encoder configured for VMOMI. 68 func NewJSONEncoder(w *bytes.Buffer) *json.Encoder { 69 enc := json.NewEncoder(w) 70 enc.SetDiscriminator( 71 discriminatorMemberName, 72 primitiveValueMemberName, 73 json.DiscriminatorEncodeTypeNameRootValue| 74 json.DiscriminatorEncodeTypeNameAllObjects, 75 ) 76 enc.SetTypeToDiscriminatorFunc(VmomiTypeName) 77 return enc 78 } 79 80 // VmomiTypeName computes the VMOMI type name of a go type. It uses a lookup 81 // table for VMOMI primitive types and the default discriminator function for 82 // other types. 83 func VmomiTypeName(t reflect.Type) (discriminator string) { 84 // Look up primitive type names from VMOMI protocol 85 if name, ok := discriminatorNamesRegistry[t]; ok { 86 return name 87 } 88 name := json.DefaultDiscriminatorFunc(t) 89 return name 90 }