feat: unify marshal behavior
This commit is contained in:
parent
4d62828fa6
commit
5a757074ea
5 changed files with 165 additions and 16 deletions
23
go.sum
Normal file
23
go.sum
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
code.icb4dc0.de/buildr/api v0.0.0-20230817151157-dbc0adad8f8b h1:pZDHPJCMRw3UM1Jd0y7XnPZaDOzZ5du17EvW09mgb4g=
|
||||||
|
code.icb4dc0.de/buildr/api v0.0.0-20230817151157-dbc0adad8f8b/go.mod h1:Bxt+fw/9hH7/WESz3asYBIWPr81UlUMEleXJGTqX6ys=
|
||||||
|
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||||
|
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||||
|
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||||
|
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
|
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||||
|
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
|
golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14=
|
||||||
|
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
|
||||||
|
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
|
||||||
|
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
|
||||||
|
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||||
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20230815205213-6bfd019c3878 h1:lv6/DhyiFFGsmzxbsUUTOkN29II+zeWHxvT8Lpdxsv0=
|
||||||
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20230815205213-6bfd019c3878/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M=
|
||||||
|
google.golang.org/grpc v1.57.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw=
|
||||||
|
google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo=
|
||||||
|
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||||
|
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||||
|
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
||||||
|
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
71
hcl/tag.go
Normal file
71
hcl/tag.go
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
package hcl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
ElementTypeAttribute ElementType = "attr"
|
||||||
|
ElementTypeBlock ElementType = "block"
|
||||||
|
ElementTypeLabel ElementType = "label"
|
||||||
|
ElementTypeRemain ElementType = "remain"
|
||||||
|
)
|
||||||
|
|
||||||
|
var ErrNoHclTag = errors.New("no hcl tag")
|
||||||
|
|
||||||
|
type ElementType string
|
||||||
|
|
||||||
|
type FieldMeta struct {
|
||||||
|
Name string
|
||||||
|
Type ElementType
|
||||||
|
Optional bool
|
||||||
|
Ignore bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExtractFieldMeta(t reflect.StructField, readTagName, writeTagName string) (FieldMeta, error) {
|
||||||
|
hclTag, present := t.Tag.Lookup(readTagName)
|
||||||
|
if !present {
|
||||||
|
return FieldMeta{}, ErrNoHclTag
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg := FieldMeta{
|
||||||
|
Name: t.Name,
|
||||||
|
Type: ElementTypeAttribute,
|
||||||
|
}
|
||||||
|
|
||||||
|
if hclWriteTag, present := t.Tag.Lookup(writeTagName); present && hclWriteTag == "-" {
|
||||||
|
cfg.Ignore = true
|
||||||
|
|
||||||
|
return cfg, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
split := strings.Split(hclTag, ",")
|
||||||
|
|
||||||
|
if len(split) > 0 && split[0] != "" {
|
||||||
|
cfg.Name = split[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(split) > 1 {
|
||||||
|
switch split[1] {
|
||||||
|
case "":
|
||||||
|
fallthrough
|
||||||
|
case "attr":
|
||||||
|
cfg.Type = ElementTypeAttribute
|
||||||
|
case "optional":
|
||||||
|
cfg.Optional = true
|
||||||
|
case "label":
|
||||||
|
cfg.Type = ElementTypeLabel
|
||||||
|
case "block":
|
||||||
|
cfg.Type = ElementTypeBlock
|
||||||
|
case "remain":
|
||||||
|
cfg.Type = ElementTypeRemain
|
||||||
|
default:
|
||||||
|
return FieldMeta{}, fmt.Errorf("unknown element type %q", split[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cfg, nil
|
||||||
|
}
|
26
protocol/config.go
Normal file
26
protocol/config.go
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
package protocol
|
||||||
|
|
||||||
|
var (
|
||||||
|
_ marshalConfigOption = WithTagName("hcl")
|
||||||
|
_ unmarshalConfigOption = WithTagName("hcl")
|
||||||
|
)
|
||||||
|
|
||||||
|
type WithTagName string
|
||||||
|
|
||||||
|
func (o WithTagName) applyToMarshalConfig(cfg *marshalConfig) {
|
||||||
|
cfg.TagName = string(o)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o WithTagName) applyToUnmarshalConfig(cfg *unmarshalConfig) {
|
||||||
|
cfg.TagName = string(o)
|
||||||
|
}
|
||||||
|
|
||||||
|
func defaultConfig() protocolConfig {
|
||||||
|
return protocolConfig{
|
||||||
|
TagName: "hcl",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type protocolConfig struct {
|
||||||
|
TagName string
|
||||||
|
}
|
|
@ -11,9 +11,17 @@ import (
|
||||||
|
|
||||||
var ErrExpectedStruct = errors.New("expected struct")
|
var ErrExpectedStruct = errors.New("expected struct")
|
||||||
|
|
||||||
func Marshal(in any) (*rpcv1.ModuleSpec, error) {
|
type marshalConfigOption interface {
|
||||||
|
applyToMarshalConfig(cfg *marshalConfig)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Marshal(in any, opts ...marshalConfigOption) (*rpcv1.ModuleSpec, error) {
|
||||||
cfg := marshalConfig{
|
cfg := marshalConfig{
|
||||||
TagName: "hcl",
|
protocolConfig: defaultConfig(),
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, opt := range opts {
|
||||||
|
opt.applyToMarshalConfig(&cfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
val := reflect.ValueOf(in)
|
val := reflect.ValueOf(in)
|
||||||
|
@ -29,7 +37,7 @@ func Marshal(in any) (*rpcv1.ModuleSpec, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type marshalConfig struct {
|
type marshalConfig struct {
|
||||||
TagName string
|
protocolConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg marshalConfig) marshal(in reflect.Value) (*rpcv1.ModuleSpec, error) {
|
func (cfg marshalConfig) marshal(in reflect.Value) (*rpcv1.ModuleSpec, error) {
|
||||||
|
@ -39,8 +47,6 @@ func (cfg marshalConfig) marshal(in reflect.Value) (*rpcv1.ModuleSpec, error) {
|
||||||
Values: make(map[string]*rpcv1.ModuleSpec_Value, numField),
|
Values: make(map[string]*rpcv1.ModuleSpec_Value, numField),
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO consider tag for field name
|
|
||||||
|
|
||||||
inputType := in.Type()
|
inputType := in.Type()
|
||||||
|
|
||||||
for i := 0; i < numField; i++ {
|
for i := 0; i < numField; i++ {
|
||||||
|
@ -116,6 +122,7 @@ func (cfg marshalConfig) fieldName(field reflect.StructField) string {
|
||||||
func (cfg marshalConfig) mapValue(in reflect.Value) *rpcv1.ModuleSpec_Value {
|
func (cfg marshalConfig) mapValue(in reflect.Value) *rpcv1.ModuleSpec_Value {
|
||||||
result := &rpcv1.ModuleSpec_Value{
|
result := &rpcv1.ModuleSpec_Value{
|
||||||
Type: rpcv1.ModuleSpec_ValueTypeMap,
|
Type: rpcv1.ModuleSpec_ValueTypeMap,
|
||||||
|
Kind: rpcv1.ModuleSpec_ValueKindAttribute,
|
||||||
ComplexValue: make(map[string]*rpcv1.ModuleSpec_Value, in.Len()),
|
ComplexValue: make(map[string]*rpcv1.ModuleSpec_Value, in.Len()),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,6 +139,7 @@ func (cfg marshalConfig) structValue(in reflect.Value) *rpcv1.ModuleSpec_Value {
|
||||||
numFields := inputType.NumField()
|
numFields := inputType.NumField()
|
||||||
result := &rpcv1.ModuleSpec_Value{
|
result := &rpcv1.ModuleSpec_Value{
|
||||||
Type: rpcv1.ModuleSpec_ValueTypeObject,
|
Type: rpcv1.ModuleSpec_ValueTypeObject,
|
||||||
|
Kind: rpcv1.ModuleSpec_ValueKindAttribute,
|
||||||
ComplexValue: make(map[string]*rpcv1.ModuleSpec_Value, numFields),
|
ComplexValue: make(map[string]*rpcv1.ModuleSpec_Value, numFields),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,6 +158,7 @@ func (cfg marshalConfig) structValue(in reflect.Value) *rpcv1.ModuleSpec_Value {
|
||||||
func boolValue(in bool) *rpcv1.ModuleSpec_Value {
|
func boolValue(in bool) *rpcv1.ModuleSpec_Value {
|
||||||
return &rpcv1.ModuleSpec_Value{
|
return &rpcv1.ModuleSpec_Value{
|
||||||
Type: rpcv1.ModuleSpec_ValueTypeSingle,
|
Type: rpcv1.ModuleSpec_ValueTypeSingle,
|
||||||
|
Kind: rpcv1.ModuleSpec_ValueKindAttribute,
|
||||||
SingleValue: &rpcv1.ModuleSpec_Value_BoolValue{
|
SingleValue: &rpcv1.ModuleSpec_Value_BoolValue{
|
||||||
BoolValue: in,
|
BoolValue: in,
|
||||||
},
|
},
|
||||||
|
@ -159,6 +168,7 @@ func boolValue(in bool) *rpcv1.ModuleSpec_Value {
|
||||||
func boolSliceValue(val reflect.Value) *rpcv1.ModuleSpec_Value {
|
func boolSliceValue(val reflect.Value) *rpcv1.ModuleSpec_Value {
|
||||||
result := &rpcv1.ModuleSpec_Value{
|
result := &rpcv1.ModuleSpec_Value{
|
||||||
Type: rpcv1.ModuleSpec_ValueTypeBoolSlice,
|
Type: rpcv1.ModuleSpec_ValueTypeBoolSlice,
|
||||||
|
Kind: rpcv1.ModuleSpec_ValueKindAttribute,
|
||||||
BoolValues: make([]bool, 0, val.Len()),
|
BoolValues: make([]bool, 0, val.Len()),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,6 +182,7 @@ func boolSliceValue(val reflect.Value) *rpcv1.ModuleSpec_Value {
|
||||||
func intValue[T Integer](in T) *rpcv1.ModuleSpec_Value {
|
func intValue[T Integer](in T) *rpcv1.ModuleSpec_Value {
|
||||||
return &rpcv1.ModuleSpec_Value{
|
return &rpcv1.ModuleSpec_Value{
|
||||||
Type: rpcv1.ModuleSpec_ValueTypeSingle,
|
Type: rpcv1.ModuleSpec_ValueTypeSingle,
|
||||||
|
Kind: rpcv1.ModuleSpec_ValueKindAttribute,
|
||||||
SingleValue: &rpcv1.ModuleSpec_Value_IntValue{
|
SingleValue: &rpcv1.ModuleSpec_Value_IntValue{
|
||||||
IntValue: int64(in),
|
IntValue: int64(in),
|
||||||
},
|
},
|
||||||
|
@ -181,6 +192,7 @@ func intValue[T Integer](in T) *rpcv1.ModuleSpec_Value {
|
||||||
func intSliceValue(val reflect.Value, selector func(v reflect.Value) int64) *rpcv1.ModuleSpec_Value {
|
func intSliceValue(val reflect.Value, selector func(v reflect.Value) int64) *rpcv1.ModuleSpec_Value {
|
||||||
result := &rpcv1.ModuleSpec_Value{
|
result := &rpcv1.ModuleSpec_Value{
|
||||||
Type: rpcv1.ModuleSpec_ValueTypeIntSlice,
|
Type: rpcv1.ModuleSpec_ValueTypeIntSlice,
|
||||||
|
Kind: rpcv1.ModuleSpec_ValueKindAttribute,
|
||||||
IntValues: make([]int64, 0, val.Len()),
|
IntValues: make([]int64, 0, val.Len()),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,6 +206,7 @@ func intSliceValue(val reflect.Value, selector func(v reflect.Value) int64) *rpc
|
||||||
func floatValue[T Float](in T) *rpcv1.ModuleSpec_Value {
|
func floatValue[T Float](in T) *rpcv1.ModuleSpec_Value {
|
||||||
return &rpcv1.ModuleSpec_Value{
|
return &rpcv1.ModuleSpec_Value{
|
||||||
Type: rpcv1.ModuleSpec_ValueTypeSingle,
|
Type: rpcv1.ModuleSpec_ValueTypeSingle,
|
||||||
|
Kind: rpcv1.ModuleSpec_ValueKindAttribute,
|
||||||
SingleValue: &rpcv1.ModuleSpec_Value_DoubleValue{
|
SingleValue: &rpcv1.ModuleSpec_Value_DoubleValue{
|
||||||
DoubleValue: float64(in),
|
DoubleValue: float64(in),
|
||||||
},
|
},
|
||||||
|
@ -203,6 +216,7 @@ func floatValue[T Float](in T) *rpcv1.ModuleSpec_Value {
|
||||||
func floatSliceValue(val reflect.Value) *rpcv1.ModuleSpec_Value {
|
func floatSliceValue(val reflect.Value) *rpcv1.ModuleSpec_Value {
|
||||||
result := &rpcv1.ModuleSpec_Value{
|
result := &rpcv1.ModuleSpec_Value{
|
||||||
Type: rpcv1.ModuleSpec_ValueTypeDoubleSlice,
|
Type: rpcv1.ModuleSpec_ValueTypeDoubleSlice,
|
||||||
|
Kind: rpcv1.ModuleSpec_ValueKindAttribute,
|
||||||
DoubleValues: make([]float64, 0, val.Len()),
|
DoubleValues: make([]float64, 0, val.Len()),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,6 +230,7 @@ func floatSliceValue(val reflect.Value) *rpcv1.ModuleSpec_Value {
|
||||||
func stringValue(in string) *rpcv1.ModuleSpec_Value {
|
func stringValue(in string) *rpcv1.ModuleSpec_Value {
|
||||||
return &rpcv1.ModuleSpec_Value{
|
return &rpcv1.ModuleSpec_Value{
|
||||||
Type: rpcv1.ModuleSpec_ValueTypeSingle,
|
Type: rpcv1.ModuleSpec_ValueTypeSingle,
|
||||||
|
Kind: rpcv1.ModuleSpec_ValueKindAttribute,
|
||||||
SingleValue: &rpcv1.ModuleSpec_Value_StringValue{
|
SingleValue: &rpcv1.ModuleSpec_Value_StringValue{
|
||||||
StringValue: in,
|
StringValue: in,
|
||||||
},
|
},
|
||||||
|
@ -225,6 +240,7 @@ func stringValue(in string) *rpcv1.ModuleSpec_Value {
|
||||||
func stringSliceValue(val reflect.Value) *rpcv1.ModuleSpec_Value {
|
func stringSliceValue(val reflect.Value) *rpcv1.ModuleSpec_Value {
|
||||||
result := &rpcv1.ModuleSpec_Value{
|
result := &rpcv1.ModuleSpec_Value{
|
||||||
Type: rpcv1.ModuleSpec_ValueTypeStringSlice,
|
Type: rpcv1.ModuleSpec_ValueTypeStringSlice,
|
||||||
|
Kind: rpcv1.ModuleSpec_ValueKindAttribute,
|
||||||
StringValues: make([]string, 0, val.Len()),
|
StringValues: make([]string, 0, val.Len()),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,16 +9,25 @@ import (
|
||||||
rpcv1 "code.icb4dc0.de/buildr/api/generated/rpc/v1"
|
rpcv1 "code.icb4dc0.de/buildr/api/generated/rpc/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var ErrUnmatchingType = errors.New("field type does not match wire value")
|
||||||
ErrUnmatchingType = errors.New("field type does not match wire value")
|
|
||||||
)
|
|
||||||
|
|
||||||
func Unmarshal(input *rpcv1.ModuleSpec, into any) error {
|
type unmarshalConfigOption interface {
|
||||||
|
applyToUnmarshalConfig(cfg *unmarshalConfig)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Unmarshal(input *rpcv1.ModuleSpec, into any, opts ...unmarshalConfigOption) error {
|
||||||
if u, ok := into.(SpecUnmarshaler); ok {
|
if u, ok := into.(SpecUnmarshaler); ok {
|
||||||
return u.UnmarshalModuleSpec(input)
|
return u.UnmarshalModuleSpec(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cfg := unmarshalConfig{
|
||||||
|
protocolConfig: defaultConfig(),
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, opt := range opts {
|
||||||
|
opt.applyToUnmarshalConfig(&cfg)
|
||||||
|
}
|
||||||
|
|
||||||
val := reflect.ValueOf(into)
|
val := reflect.ValueOf(into)
|
||||||
|
|
||||||
switch val.Kind() {
|
switch val.Kind() {
|
||||||
|
@ -26,10 +35,14 @@ func Unmarshal(input *rpcv1.ModuleSpec, into any) error {
|
||||||
default:
|
default:
|
||||||
return errors.New("into value must be a pointer")
|
return errors.New("into value must be a pointer")
|
||||||
}
|
}
|
||||||
return unmarshal(input.Values, val.Elem(), reflect.TypeOf(into).Elem())
|
return cfg.unmarshal(input.Values, val.Elem(), reflect.TypeOf(into).Elem())
|
||||||
}
|
}
|
||||||
|
|
||||||
func unmarshal(input map[string]*rpcv1.ModuleSpec_Value, into reflect.Value, intoType reflect.Type) error {
|
type unmarshalConfig struct {
|
||||||
|
protocolConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg unmarshalConfig) unmarshal(input map[string]*rpcv1.ModuleSpec_Value, into reflect.Value, intoType reflect.Type) error {
|
||||||
for i := 0; i < intoType.NumField(); i++ {
|
for i := 0; i < intoType.NumField(); i++ {
|
||||||
tf := intoType.Field(i)
|
tf := intoType.Field(i)
|
||||||
if !tf.IsExported() {
|
if !tf.IsExported() {
|
||||||
|
@ -57,7 +70,7 @@ func unmarshal(input map[string]*rpcv1.ModuleSpec_Value, into reflect.Value, int
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if mapped, err := mapSpecValueTo(val, tf.Type); err != nil {
|
if mapped, err := cfg.mapSpecValueTo(val, tf.Type); err != nil {
|
||||||
return err
|
return err
|
||||||
} else if into.Type().Kind() == reflect.Pointer {
|
} else if into.Type().Kind() == reflect.Pointer {
|
||||||
into.Elem().Field(i).Set(mapped)
|
into.Elem().Field(i).Set(mapped)
|
||||||
|
@ -69,21 +82,21 @@ func unmarshal(input map[string]*rpcv1.ModuleSpec_Value, into reflect.Value, int
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func mapSpecValueTo(val *rpcv1.ModuleSpec_Value, targetType reflect.Type) (reflect.Value, error) {
|
func (cfg unmarshalConfig) mapSpecValueTo(val *rpcv1.ModuleSpec_Value, targetType reflect.Type) (reflect.Value, error) {
|
||||||
switch val.Type {
|
switch val.Type {
|
||||||
case rpcv1.ModuleSpec_ValueTypeUnknown:
|
case rpcv1.ModuleSpec_ValueTypeUnknown:
|
||||||
return reflect.Value{}, fmt.Errorf("%w: expected %s", ErrUnmatchingType, targetType.String())
|
return reflect.Value{}, fmt.Errorf("%w: expected %s", ErrUnmatchingType, targetType.String())
|
||||||
case rpcv1.ModuleSpec_ValueTypeObject:
|
case rpcv1.ModuleSpec_ValueTypeObject:
|
||||||
if targetType.Kind() == reflect.Struct {
|
if targetType.Kind() == reflect.Struct {
|
||||||
structVal := reflect.New(targetType)
|
structVal := reflect.New(targetType)
|
||||||
if err := unmarshal(val.ComplexValue, structVal, targetType); err != nil {
|
if err := cfg.unmarshal(val.ComplexValue, structVal, targetType); err != nil {
|
||||||
return reflect.Value{}, err
|
return reflect.Value{}, err
|
||||||
} else {
|
} else {
|
||||||
return structVal.Elem(), nil
|
return structVal.Elem(), nil
|
||||||
}
|
}
|
||||||
} else if targetType.Kind() == reflect.Pointer && targetType.Elem().Kind() == reflect.Struct {
|
} else if targetType.Kind() == reflect.Pointer && targetType.Elem().Kind() == reflect.Struct {
|
||||||
structVal := reflect.New(targetType.Elem())
|
structVal := reflect.New(targetType.Elem())
|
||||||
if err := unmarshal(val.ComplexValue, structVal, targetType.Elem()); err != nil {
|
if err := cfg.unmarshal(val.ComplexValue, structVal, targetType.Elem()); err != nil {
|
||||||
return reflect.Value{}, err
|
return reflect.Value{}, err
|
||||||
} else {
|
} else {
|
||||||
return structVal, nil
|
return structVal, nil
|
||||||
|
@ -99,7 +112,7 @@ func mapSpecValueTo(val *rpcv1.ModuleSpec_Value, targetType reflect.Type) (refle
|
||||||
mapVal := reflect.MakeMap(targetType)
|
mapVal := reflect.MakeMap(targetType)
|
||||||
|
|
||||||
for k, v := range val.ComplexValue {
|
for k, v := range val.ComplexValue {
|
||||||
if mappedVal, err := mapSpecValueTo(v, targetType.Elem()); err != nil {
|
if mappedVal, err := cfg.mapSpecValueTo(v, targetType.Elem()); err != nil {
|
||||||
return reflect.Value{}, err
|
return reflect.Value{}, err
|
||||||
} else {
|
} else {
|
||||||
mapVal.SetMapIndex(reflect.ValueOf(k), mappedVal)
|
mapVal.SetMapIndex(reflect.ValueOf(k), mappedVal)
|
||||||
|
|
Loading…
Reference in a new issue