Fix empty string int marshalling in go 1.14

This commit is contained in:
Paul Tyng
2020-03-26 16:13:19 -04:00
parent d076e78005
commit f74d29bd54
5 changed files with 102 additions and 38 deletions

33
unifi/json.go Normal file
View File

@@ -0,0 +1,33 @@
package unifi
import (
"strconv"
"strings"
)
// emptyStringInt was created due to the behavior change in
// Go 1.14 with json.Number's handling of empty string.
type emptyStringInt int
func (e *emptyStringInt) UnmarshalJSON(b []byte) error {
if len(b) == 0 {
return nil
}
if string(b) == `""` {
return nil
}
var err error
s := string(b)
if strings.HasPrefix(s, `"`) && strings.HasSuffix(s, `"`) {
s, err = strconv.Unquote(s)
if err != nil {
return err
}
}
i, err := strconv.Atoi(s)
if err != nil {
return err
}
*e = emptyStringInt(i)
return nil
}

View File

@@ -9,35 +9,21 @@ import (
func (dst *Network) UnmarshalJSON(b []byte) error {
type Alias Network
aux := &struct {
VLAN json.Number `json:"vlan"`
DHCPDLeaseTime json.Number `json:"dhcpd_leasetime"`
VLAN emptyStringInt `json:"vlan"`
DHCPDLeaseTime emptyStringInt `json:"dhcpd_leasetime"`
*Alias
}{
Alias: (*Alias)(dst),
}
err := json.Unmarshal(b, &aux)
if err != nil {
return err
return fmt.Errorf("unable to unmarshal alias: %w", err)
}
dst.VLAN = 0
if aux.VLAN.String() != "" {
n, err := aux.VLAN.Int64()
if err != nil {
return err
}
dst.VLAN = int(n)
}
dst.DHCPDLeaseTime = 0
if aux.DHCPDLeaseTime.String() != "" {
n, err := aux.DHCPDLeaseTime.Int64()
if err != nil {
return err
}
dst.DHCPDLeaseTime = int(n)
}
dst.VLAN = int(aux.VLAN)
dst.DHCPDLeaseTime = int(aux.DHCPDLeaseTime)
return nil
}

53
unifi/network_test.go Normal file
View File

@@ -0,0 +1,53 @@
package unifi_test
import (
"encoding/json"
"reflect"
"testing"
"github.com/paultyng/go-unifi/unifi"
)
func TestNetworkUnmarshalJSON(t *testing.T) {
for n, c := range map[string]struct {
expected unifi.Network
json string
}{
"int vlan": {
expected: unifi.Network{VLAN: 1},
json: `{ "vlan": 1 }`,
},
"string vlan": {
expected: unifi.Network{VLAN: 1},
json: `{ "vlan": "1" }`,
},
"empty string vlan": {
expected: unifi.Network{VLAN: 0},
json: `{ "vlan": "" }`,
},
"int dhcpd_leasetime": {
expected: unifi.Network{DHCPDLeaseTime: 1},
json: `{ "dhcpd_leasetime": 1 }`,
},
"string dhcpd_leasetime": {
expected: unifi.Network{DHCPDLeaseTime: 1},
json: `{ "dhcpd_leasetime": "1" }`,
},
"empty string dhcpd_leasetime": {
expected: unifi.Network{DHCPDLeaseTime: 0},
json: `{ "dhcpd_leasetime": "" }`,
},
} {
t.Run(n, func(t *testing.T) {
var actual unifi.Network
err := json.Unmarshal(([]byte)(c.json), &actual)
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(c.expected, actual) {
t.Fatalf("not equal:\nexpected: %#v\nactual: %#v", c.expected, actual)
}
})
}
}

View File

@@ -8,23 +8,19 @@ import (
func (n *WLAN) UnmarshalJSON(b []byte) error {
type Alias WLAN
aux := &struct {
VLAN json.Number `json:"vlan"`
VLAN emptyStringInt `json:"vlan"`
*Alias
}{
Alias: (*Alias)(n),
}
err := json.Unmarshal(b, &aux)
if err != nil {
return err
}
n.VLAN = 0
if aux.VLAN.String() != "" {
vlan, err := aux.VLAN.Int64()
if err != nil {
return err
}
n.VLAN = int(vlan)
}
n.VLAN = int(aux.VLAN)
return nil
}

View File

@@ -8,23 +8,19 @@ import (
func (n *WLANGroup) UnmarshalJSON(b []byte) error {
type Alias WLANGroup
aux := &struct {
Maxsta json.Number `json:"maxsta"`
Maxsta emptyStringInt `json:"maxsta"`
*Alias
}{
Alias: (*Alias)(n),
}
err := json.Unmarshal(b, &aux)
if err != nil {
return err
}
n.Maxsta = 0
if aux.Maxsta.String() != "" {
maxsta, err := aux.Maxsta.Int64()
if err != nil {
return err
}
n.Maxsta = int(maxsta)
}
n.Maxsta = int(aux.Maxsta)
return nil
}