Fixing unmarshalling of numberOrString
New unmarshalling rules for fields which could be numeric or string values were not properly typecasted upon being deserialized. Cleaned up the api template file and moved custom unmarshalling type logic into go code out of the template.
This commit is contained in:
committed by
Paul Tyng
parent
4ab4036985
commit
fbed685c37
@@ -2,21 +2,18 @@
|
||||
|
||||
{{ define "field" }}
|
||||
{{ .FieldName }} {{ if .IsArray }}[]{{end}}{{ .FieldType }} `json:"{{ .JSONName }}{{ if .OmitEmpty }},omitempty{{ end }}"` {{ if .FieldValidation }}// {{ .FieldValidation }}{{ end }} {{- end }}
|
||||
{{ define "field-emptyStringInt" }}
|
||||
{{- if ne .FieldType "int" }}{{else}}
|
||||
{{ .FieldName }} {{ if .IsArray }}[]{{end}}emptyStringInt `json:"{{ .JSONName }}{{ if .OmitEmpty }}{{ end }}"`{{ end }} {{- end }}
|
||||
{{ define "field-numberOrString" }}
|
||||
{{- /* this is kind of a hack, probably a better way to do this when looking at the normalized validation */ -}}
|
||||
{{- if and (eq .FieldType "string") (or (eq .JSONName "channel") (eq .JSONName "backup_channel") (eq .JSONName "tx_power")) }}
|
||||
{{ .FieldName }} {{ if .IsArray }}[]{{end}}numberOrString `json:"{{ .JSONName }}{{ if .OmitEmpty }}{{ end }}"`{{ end }} {{- end }}
|
||||
{{ define "field-customUnmarshalType" }}
|
||||
{{- if eq .CustomUnmarshalType "" }}{{else}}
|
||||
{{ .FieldName }} {{ if .IsArray }}[]{{end}}{{ .CustomUnmarshalType }} `json:"{{ .JSONName }}{{ if .OmitEmpty }}{{ end }}"`{{ end }} {{- end }}
|
||||
{{ define "typecast" }}
|
||||
{{- if eq .FieldType "int" }}{{- if .IsArray }}
|
||||
dst.{{ .FieldName }}= make([]int, len(aux.{{ .FieldName }}))
|
||||
{{- if eq .CustomUnmarshalType "" }}{{else}}
|
||||
{{- if .IsArray }}
|
||||
dst.{{ .FieldName }}= make([]{{ .FieldType }}, len(aux.{{ .FieldName }}))
|
||||
for i, v := range aux.{{ .FieldName }} {
|
||||
dst.{{ .FieldName }}[i] = int(v)
|
||||
dst.{{ .FieldName }}[i] = {{ .FieldType }}(v)
|
||||
}
|
||||
{{- else }}
|
||||
dst.{{ .FieldName }} = int(aux.{{ .FieldName }})
|
||||
dst.{{ .FieldName }} = {{ .FieldType }}(aux.{{ .FieldName }})
|
||||
{{- end }}{{- end }}{{- end }}
|
||||
{{ define "field-embed" }}
|
||||
{{ .FieldName }} {{ if .IsArray }}[]{{end}}{{ if not .Fields }}{{ .FieldType }}{{ else }}struct {
|
||||
@@ -59,7 +56,7 @@ func (dst *{{ $k }}) UnmarshalJSON(b []byte) error {
|
||||
type Alias {{ $k }}
|
||||
aux := &struct {
|
||||
{{- range $fk, $fv := $v.Fields }}{{ if not $fv }}
|
||||
{{- else }}{{- template "field-emptyStringInt" $fv }}{{- template "field-numberOrString" $fv }}{{ end }}{{- end }}
|
||||
{{- else }}{{- template "field-customUnmarshalType" $fv }}{{ end }}{{- end }}
|
||||
|
||||
*Alias
|
||||
}{
|
||||
|
||||
@@ -105,6 +105,7 @@ type FieldInfo struct {
|
||||
OmitEmpty bool
|
||||
IsArray bool
|
||||
Fields map[string]*FieldInfo
|
||||
CustomUnmarshalType string
|
||||
}
|
||||
|
||||
func NewResource(structName string, resourcePath string) *Resource {
|
||||
@@ -278,6 +279,16 @@ func main() {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
case "ChannelPlan":
|
||||
resource.FieldProcessor = func(name string, f *FieldInfo) error {
|
||||
switch name {
|
||||
case "Channel", "BackupChannel", "TxPower":
|
||||
if f.FieldType == "string" {
|
||||
f.CustomUnmarshalType = "numberOrString"
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
case "Device":
|
||||
resource.FieldProcessor = func(name string, f *FieldInfo) error {
|
||||
switch name {
|
||||
@@ -285,6 +296,11 @@ func main() {
|
||||
f.FieldType = "float64"
|
||||
case "StpPriority", "Ht":
|
||||
f.FieldType = "string"
|
||||
f.CustomUnmarshalType = ""
|
||||
case "Channel", "BackupChannel", "TxPower":
|
||||
if f.FieldType == "string" {
|
||||
f.CustomUnmarshalType = "numberOrString"
|
||||
}
|
||||
}
|
||||
|
||||
f.OmitEmpty = true
|
||||
@@ -294,6 +310,7 @@ func main() {
|
||||
resource.FieldProcessor = func(name string, f *FieldInfo) error {
|
||||
if strings.HasSuffix(name, "Timeout") && name != "ArpCacheTimeout" {
|
||||
f.FieldType = "int"
|
||||
f.CustomUnmarshalType = "emptyStringInt"
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -304,6 +321,7 @@ func main() {
|
||||
f.FieldType = "bool"
|
||||
case "LastSeen":
|
||||
f.FieldType = "int"
|
||||
f.CustomUnmarshalType = "emptyStringInt"
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -416,6 +434,7 @@ func (r *Resource) fieldInfoFromValidation(name string, validation interface{})
|
||||
|
||||
omitEmpty = true
|
||||
fieldInfo, err = NewFieldInfo(fieldName, name, "int", fieldValidation, omitEmpty, false), nil
|
||||
fieldInfo.CustomUnmarshalType = "emptyStringInt"
|
||||
return fieldInfo, r.FieldProcessor(fieldName, fieldInfo)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,6 +133,9 @@ func (dst *ChannelPlanRadioTable) UnmarshalJSON(b []byte) error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to unmarshal alias: %w", err)
|
||||
}
|
||||
dst.BackupChannel = string(aux.BackupChannel)
|
||||
dst.Channel = string(aux.Channel)
|
||||
dst.TxPower = string(aux.TxPower)
|
||||
dst.Width = int(aux.Width)
|
||||
|
||||
return nil
|
||||
|
||||
@@ -315,9 +315,12 @@ func (dst *DeviceRadioTable) UnmarshalJSON(b []byte) error {
|
||||
}
|
||||
dst.AntennaGain = int(aux.AntennaGain)
|
||||
dst.AntennaID = int(aux.AntennaID)
|
||||
dst.BackupChannel = string(aux.BackupChannel)
|
||||
dst.Channel = string(aux.Channel)
|
||||
dst.Maxsta = int(aux.Maxsta)
|
||||
dst.MinRssi = int(aux.MinRssi)
|
||||
dst.SensLevel = int(aux.SensLevel)
|
||||
dst.TxPower = string(aux.TxPower)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user