Skip to content

Commit

Permalink
Use bytes interface value for zero native type struct fields instead …
Browse files Browse the repository at this point in the history
…of dynamic list (#981)

* Use bytes interface value for zero native type struct fields instead of dynamic list

If a struct has a byte array/slice field and it happens to be the zero
value, a dynamic list object was returned. This caused issues with
functions taking `Bytes` via arguments, as the type checker will accept
such functions, but they might fail at runtime.

To work around this, the raw bytes array/slice is returned in case of an
zero value.

* Remove unused special handling cases for retrieving field values

For most types, it is good enough to use the raw interface values for
null types. Hence the logic of getFieldValue has been adjusted to remove
some special handling code.
  • Loading branch information
patrickpichler authored Jul 31, 2024
1 parent c9164bc commit 1f51886
Showing 1 changed file with 4 additions and 9 deletions.
13 changes: 4 additions & 9 deletions ext/native.go
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ func (tp *nativeTypeProvider) FindStructFieldType(typeName, fieldName string) (*
GetFrom: func(obj any) (any, error) {
refVal := reflect.Indirect(reflect.ValueOf(obj))
refField := valueFieldByName(tp.options.parseStructTags, refVal, fieldName)
return getFieldValue(tp, refField), nil
return getFieldValue(refField), nil
},
}, true
}
Expand Down Expand Up @@ -704,21 +704,16 @@ func (t *nativeType) hasField(fieldName string) (reflect.StructField, bool) {
}

func adaptFieldValue(adapter types.Adapter, refField reflect.Value) ref.Val {
return adapter.NativeToValue(getFieldValue(adapter, refField))
return adapter.NativeToValue(getFieldValue(refField))
}

func getFieldValue(adapter types.Adapter, refField reflect.Value) any {
func getFieldValue(refField reflect.Value) any {
if refField.IsZero() {
switch refField.Kind() {
case reflect.Array, reflect.Slice:
return types.NewDynamicList(adapter, []ref.Val{})
case reflect.Map:
return types.NewDynamicMap(adapter, map[ref.Val]ref.Val{})
case reflect.Struct:
if refField.Type() == timestampType {
return types.Timestamp{Time: time.Unix(0, 0)}
return time.Unix(0, 0)
}
return reflect.New(refField.Type()).Elem().Interface()
case reflect.Pointer:
return reflect.New(refField.Type().Elem()).Interface()
}
Expand Down

0 comments on commit 1f51886

Please sign in to comment.