From 9c2ef9cad55e35213692d2b1ccfb14e01cb8b477 Mon Sep 17 00:00:00 2001 From: Filippe Spolti Date: Tue, 7 Feb 2023 23:01:40 -0300 Subject: [PATCH] Fixes unsupported AST kind *ast.InterfaceType on the custon Object type (#139) Signed-off-by: Spolti --- hack/deepcopy-gen.sh | 2 +- model/object.go | 152 ++++++++++----------------------- model/parallel_state.go | 8 +- model/zz_generated.deepcopy.go | 6 +- 4 files changed, 55 insertions(+), 113 deletions(-) diff --git a/hack/deepcopy-gen.sh b/hack/deepcopy-gen.sh index 353a682..2ef0fdf 100755 --- a/hack/deepcopy-gen.sh +++ b/hack/deepcopy-gen.sh @@ -41,7 +41,7 @@ if [ "${GENS}" = "all" ] || grep -qw "deepcopy" <<<"${GENS}"; then echo "Generating deepcopy funcs" export GO111MODULE=on # for debug purposes, increase the log level by updating the -v flag to higher numbers, e.g. -v 4 - "${GOPATH}/bin/deepcopy-gen" -v 1 \ + "${GOPATH}/bin/deepcopy-gen" -v 2 \ --input-dirs ./model -O zz_generated.deepcopy \ --go-header-file "${SCRIPT_ROOT}/hack/boilerplate.txt" \ "$@" diff --git a/model/object.go b/model/object.go index f37e254..074b3dd 100644 --- a/model/object.go +++ b/model/object.go @@ -18,8 +18,6 @@ import ( "encoding/json" "fmt" "math" - "strconv" - "strings" ) // Object is used to allow integration with DeepCopy tool by replacing 'interface' generic type. @@ -32,126 +30,68 @@ import ( // - Integer - holds int32 values, JSON marshal any number to float64 by default, during the marshaling process it is // parsed to int32 // - raw - holds any not typed value, replaces the interface{} behavior. +// +// +kubebuilder:validation:Type=object type Object struct { - IObject `json:",inline"` -} - -// IObject interface that can converted into one of the three subtypes -type IObject interface { - DeepCopyIObject() IObject -} - -// raw generic subtype -type raw struct { - IObject interface{} + Type Type `json:",inline"` + IntVal int32 `json:",inline"` + StrVal string `json:",inline"` + RawValue json.RawMessage `json:",inline"` } -func (o raw) DeepCopyIObject() IObject { - return o -} +type Type int64 -// Integer int32 type -type Integer int +const ( + Integer Type = iota + String + Raw +) -func (m Integer) DeepCopyIObject() IObject { - return m +func FromInt(val int) Object { + if val > math.MaxInt32 || val < math.MinInt32 { + fmt.Println(fmt.Errorf("value: %d overflows int32", val)) + } + return Object{Type: Integer, IntVal: int32(val)} } -// String string type -type String string - -func (m String) DeepCopyIObject() IObject { - return m +func FromString(val string) Object { + return Object{Type: String, StrVal: val} } -// MarshalJSON marshal the given json object into the respective Object subtype. -func (obj Object) MarshalJSON() ([]byte, error) { - switch val := obj.IObject.(type) { - case String: - return []byte(fmt.Sprintf(`%q`, val)), nil - case Integer: - return []byte(fmt.Sprintf(`%d`, val)), nil - case raw: - custom, err := json.Marshal(&struct { - raw - }{ - val, - }) - if err != nil { - return nil, err - } - - // remove the field name and the last '}' for marshalling purposes - st := strings.Replace(string(custom), "{\"IObject\":", "", 1) - st = strings.TrimSuffix(st, "}") - return []byte(st), nil - default: - return []byte(fmt.Sprintf("%+v", obj.IObject)), nil +func FromRaw(val interface{}) Object { + custom, err := json.Marshal(val) + if err != nil { + er := fmt.Errorf("failed to parse value to Raw: %w", err) + fmt.Println(er.Error()) + return Object{} } + return Object{Type: Raw, RawValue: custom} } // UnmarshalJSON ... func (obj *Object) UnmarshalJSON(data []byte) error { - var test interface{} - if err := json.Unmarshal(data, &test); err != nil { - return err + if data[0] == '"' { + obj.Type = String + return json.Unmarshal(data, &obj.StrVal) + } else if data[0] == '{' { + obj.Type = Raw + return json.Unmarshal(data, &obj.RawValue) } - switch val := test.(type) { - case string: - var strVal String - if err := json.Unmarshal(data, &strVal); err != nil { - return err - } - obj.IObject = strVal - return nil - - case map[string]interface{}: - var cstVal raw - if err := json.Unmarshal(data, &cstVal.IObject); err != nil { - return err - } - obj.IObject = cstVal - return nil - - default: - // json parses all not typed numbers as float64, let's enforce to int32 - if valInt, parseErr := strconv.Atoi(fmt.Sprint(val)); parseErr != nil { - return fmt.Errorf("falied to parse %d to int32: %w", valInt, parseErr) - } else { - var intVal Integer - if err := json.Unmarshal(data, &intVal); err != nil { - return err - } - obj.IObject = intVal - return nil - } - } -} - -// FromInt creates an Object with an int32 value. -func FromInt(val int) Object { - if val > math.MaxInt32 || val < math.MinInt32 { - panic(fmt.Errorf("value: %d overflows int32", val)) - } - return Object{Integer(int32(val))} -} - -// FromString creates an Object with a string value. -func FromString(val string) Object { - return Object{String(val)} + obj.Type = Integer + return json.Unmarshal(data, &obj.IntVal) } -// FromRaw creates an Object with untyped values. -func FromRaw(val interface{}) Object { - var rawVal Object - data, err := json.Marshal(val) - if err != nil { - panic(err) - } - var cstVal raw - if err := json.Unmarshal(data, &cstVal.IObject); err != nil { - panic(err) +// MarshalJSON marshal the given json object into the respective Object subtype. +func (obj Object) MarshalJSON() ([]byte, error) { + switch obj.Type { + case String: + return []byte(fmt.Sprintf(`%q`, obj.StrVal)), nil + case Integer: + return []byte(fmt.Sprintf(`%d`, obj.IntVal)), nil + case Raw: + val, _ := json.Marshal(obj.RawValue) + return val, nil + default: + return []byte(fmt.Sprintf("%+v", obj)), nil } - rawVal.IObject = cstVal - return rawVal } diff --git a/model/parallel_state.go b/model/parallel_state.go index f943431..7e7ec83 100644 --- a/model/parallel_state.go +++ b/model/parallel_state.go @@ -54,14 +54,14 @@ type ParallelState struct { Timeouts *ParallelStateTimeout `json:"timeouts,omitempty"` } -func (s *ParallelState) DeepCopyState() State { - return s +func (ps *ParallelState) DeepCopyState() State { + return ps } type parallelStateForUnmarshal ParallelState // UnmarshalJSON unmarshal ParallelState object from json bytes -func (s *ParallelState) UnmarshalJSON(b []byte) error { +func (ps *ParallelState) UnmarshalJSON(b []byte) error { if len(b) == 0 { // TODO: Normalize error messages return fmt.Errorf("no bytes to unmarshal") @@ -75,7 +75,7 @@ func (s *ParallelState) UnmarshalJSON(b []byte) error { return err } - *s = ParallelState(*v) + *ps = ParallelState(*v) return nil } diff --git a/model/zz_generated.deepcopy.go b/model/zz_generated.deepcopy.go index 872570d..6117092 100644 --- a/model/zz_generated.deepcopy.go +++ b/model/zz_generated.deepcopy.go @@ -967,8 +967,10 @@ func (in *OAuth2AuthProperties) DeepCopy() *OAuth2AuthProperties { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Object) DeepCopyInto(out *Object) { *out = *in - if in.IObject != nil { - out.IObject = in.IObject.DeepCopyIObject() + if in.RawValue != nil { + in, out := &in.RawValue, &out.RawValue + *out = make(json.RawMessage, len(*in)) + copy(*out, *in) } return }