summaryrefslogtreecommitdiff
path: root/vendor/k8s.io/apimachinery/pkg/runtime/converter.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/k8s.io/apimachinery/pkg/runtime/converter.go')
-rw-r--r--vendor/k8s.io/apimachinery/pkg/runtime/converter.go122
1 files changed, 12 insertions, 110 deletions
diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/converter.go b/vendor/k8s.io/apimachinery/pkg/runtime/converter.go
index b3e8a53b3..918d0831d 100644
--- a/vendor/k8s.io/apimachinery/pkg/runtime/converter.go
+++ b/vendor/k8s.io/apimachinery/pkg/runtime/converter.go
@@ -17,7 +17,6 @@ limitations under the License.
package runtime
import (
- "bytes"
encodingjson "encoding/json"
"fmt"
"math"
@@ -32,6 +31,7 @@ import (
"k8s.io/apimachinery/pkg/conversion"
"k8s.io/apimachinery/pkg/util/json"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
+ "sigs.k8s.io/structured-merge-diff/v3/value"
"k8s.io/klog"
)
@@ -68,13 +68,8 @@ func newFieldsCache() *fieldsCache {
}
var (
- marshalerType = reflect.TypeOf(new(encodingjson.Marshaler)).Elem()
- unmarshalerType = reflect.TypeOf(new(encodingjson.Unmarshaler)).Elem()
mapStringInterfaceType = reflect.TypeOf(map[string]interface{}{})
stringType = reflect.TypeOf(string(""))
- int64Type = reflect.TypeOf(int64(0))
- float64Type = reflect.TypeOf(float64(0))
- boolType = reflect.TypeOf(bool(false))
fieldCache = newFieldsCache()
// DefaultUnstructuredConverter performs unstructured to Go typed object conversions.
@@ -208,13 +203,9 @@ func fromUnstructured(sv, dv reflect.Value) error {
}
// Check if the object has a custom JSON marshaller/unmarshaller.
- if reflect.PtrTo(dt).Implements(unmarshalerType) {
- data, err := json.Marshal(sv.Interface())
- if err != nil {
- return fmt.Errorf("error encoding %s to json: %v", st.String(), err)
- }
- unmarshaler := dv.Addr().Interface().(encodingjson.Unmarshaler)
- return unmarshaler.UnmarshalJSON(data)
+ entry := value.TypeReflectEntryOf(dv.Type())
+ if entry.CanConvertFromUnstructured() {
+ return entry.FromUnstructured(sv, dv)
}
switch dt.Kind() {
@@ -256,6 +247,7 @@ func fieldInfoFromField(structType reflect.Type, field int) *fieldInfo {
for i := range items {
if items[i] == "omitempty" {
info.omitempty = true
+ break
}
}
}
@@ -483,112 +475,28 @@ func toUnstructuredViaJSON(obj interface{}, u *map[string]interface{}) error {
return json.Unmarshal(data, u)
}
-var (
- nullBytes = []byte("null")
- trueBytes = []byte("true")
- falseBytes = []byte("false")
-)
-
-func getMarshaler(v reflect.Value) (encodingjson.Marshaler, bool) {
- // Check value receivers if v is not a pointer and pointer receivers if v is a pointer
- if v.Type().Implements(marshalerType) {
- return v.Interface().(encodingjson.Marshaler), true
- }
- // Check pointer receivers if v is not a pointer
- if v.Kind() != reflect.Ptr && v.CanAddr() {
- v = v.Addr()
- if v.Type().Implements(marshalerType) {
- return v.Interface().(encodingjson.Marshaler), true
- }
- }
- return nil, false
-}
-
func toUnstructured(sv, dv reflect.Value) error {
- // Check if the object has a custom JSON marshaller/unmarshaller.
- if marshaler, ok := getMarshaler(sv); ok {
- if sv.Kind() == reflect.Ptr && sv.IsNil() {
- // We're done - we don't need to store anything.
- return nil
- }
-
- data, err := marshaler.MarshalJSON()
+ // Check if the object has a custom string converter.
+ entry := value.TypeReflectEntryOf(sv.Type())
+ if entry.CanConvertToUnstructured() {
+ v, err := entry.ToUnstructured(sv)
if err != nil {
return err
}
- switch {
- case len(data) == 0:
- return fmt.Errorf("error decoding from json: empty value")
-
- case bytes.Equal(data, nullBytes):
- // We're done - we don't need to store anything.
-
- case bytes.Equal(data, trueBytes):
- dv.Set(reflect.ValueOf(true))
-
- case bytes.Equal(data, falseBytes):
- dv.Set(reflect.ValueOf(false))
-
- case data[0] == '"':
- var result string
- err := json.Unmarshal(data, &result)
- if err != nil {
- return fmt.Errorf("error decoding string from json: %v", err)
- }
- dv.Set(reflect.ValueOf(result))
-
- case data[0] == '{':
- result := make(map[string]interface{})
- err := json.Unmarshal(data, &result)
- if err != nil {
- return fmt.Errorf("error decoding object from json: %v", err)
- }
- dv.Set(reflect.ValueOf(result))
-
- case data[0] == '[':
- result := make([]interface{}, 0)
- err := json.Unmarshal(data, &result)
- if err != nil {
- return fmt.Errorf("error decoding array from json: %v", err)
- }
- dv.Set(reflect.ValueOf(result))
-
- default:
- var (
- resultInt int64
- resultFloat float64
- err error
- )
- if err = json.Unmarshal(data, &resultInt); err == nil {
- dv.Set(reflect.ValueOf(resultInt))
- } else if err = json.Unmarshal(data, &resultFloat); err == nil {
- dv.Set(reflect.ValueOf(resultFloat))
- } else {
- return fmt.Errorf("error decoding number from json: %v", err)
- }
+ if v != nil {
+ dv.Set(reflect.ValueOf(v))
}
-
return nil
}
-
- st, dt := sv.Type(), dv.Type()
+ st := sv.Type()
switch st.Kind() {
case reflect.String:
- if dt.Kind() == reflect.Interface && dv.NumMethod() == 0 {
- dv.Set(reflect.New(stringType))
- }
dv.Set(reflect.ValueOf(sv.String()))
return nil
case reflect.Bool:
- if dt.Kind() == reflect.Interface && dv.NumMethod() == 0 {
- dv.Set(reflect.New(boolType))
- }
dv.Set(reflect.ValueOf(sv.Bool()))
return nil
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- if dt.Kind() == reflect.Interface && dv.NumMethod() == 0 {
- dv.Set(reflect.New(int64Type))
- }
dv.Set(reflect.ValueOf(sv.Int()))
return nil
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
@@ -596,15 +504,9 @@ func toUnstructured(sv, dv reflect.Value) error {
if uVal > math.MaxInt64 {
return fmt.Errorf("unsigned value %d does not fit into int64 (overflow)", uVal)
}
- if dt.Kind() == reflect.Interface && dv.NumMethod() == 0 {
- dv.Set(reflect.New(int64Type))
- }
dv.Set(reflect.ValueOf(int64(uVal)))
return nil
case reflect.Float32, reflect.Float64:
- if dt.Kind() == reflect.Interface && dv.NumMethod() == 0 {
- dv.Set(reflect.New(float64Type))
- }
dv.Set(reflect.ValueOf(sv.Float()))
return nil
case reflect.Map: