diff --git a/unifi/json.go b/unifi/json.go new file mode 100644 index 0000000..f2c1d30 --- /dev/null +++ b/unifi/json.go @@ -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 +} diff --git a/unifi/network.go b/unifi/network.go index 4cbbbbc..f89d83b 100644 --- a/unifi/network.go +++ b/unifi/network.go @@ -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 } diff --git a/unifi/network_test.go b/unifi/network_test.go new file mode 100644 index 0000000..f2fe8ae --- /dev/null +++ b/unifi/network_test.go @@ -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) + } + }) + } +} diff --git a/unifi/wlan.go b/unifi/wlan.go index 4cccfed..ac52738 100644 --- a/unifi/wlan.go +++ b/unifi/wlan.go @@ -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 } diff --git a/unifi/wlan_group.go b/unifi/wlan_group.go index 69de902..c83b5d6 100644 --- a/unifi/wlan_group.go +++ b/unifi/wlan_group.go @@ -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 }