Skip to content

Commit 5a9e04b

Browse files
committed
First batch of XML-to-JSON conversion (#7)
* First batch of XML-to-JSON conversion * Update fixtures
1 parent fa87c0b commit 5a9e04b

34 files changed

Lines changed: 22108 additions & 403 deletions

upcloud/error.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ type Error struct {
1111
ErrorMessage string `xml:"error_message" json:"error_message"`
1212
}
1313

14+
// UnmarshalJSON is a custom unmarshaller that deals with
15+
// deeply embedded values.
1416
func (e *Error) UnmarshalJSON(b []byte) error {
1517
type localError Error
1618
v := struct {

upcloud/plan.go

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,38 @@
11
package upcloud
22

3+
import "encoding/json"
4+
35
// Plans represents a /plan response
46
type Plans struct {
5-
Plans []Plan `xml:"plan"`
7+
Plans []Plan `xml:"plan" json:"plans"`
8+
}
9+
10+
// UnmarshalJSON is a custom unmarshaller that deals with
11+
// deeply embedded values.
12+
func (s *Plans) UnmarshalJSON(b []byte) error {
13+
type planWrapper struct {
14+
Plans []Plan `json:"plan"`
15+
}
16+
17+
v := struct {
18+
Plans planWrapper `json:"plans"`
19+
}{}
20+
err := json.Unmarshal(b, &v)
21+
if err != nil {
22+
return err
23+
}
24+
25+
s.Plans = v.Plans.Plans
26+
27+
return nil
628
}
729

830
// Plan represents a pre-configured server configuration plan
931
type Plan struct {
10-
CoreNumber int `xml:"core_number"`
11-
MemoryAmount int `xml:"memory_amount"`
12-
Name string `xml:"name"`
13-
PublicTrafficOut int `xml:"public_traffic_out"`
14-
StorageSize int `xml:"storage_size"`
15-
StorageTier string `xml:"storage_tier"`
32+
CoreNumber int `xml:"core_number" json:"core_number"`
33+
MemoryAmount int `xml:"memory_amount" json:"memory_amount"`
34+
Name string `xml:"name" json:"name"`
35+
PublicTrafficOut int `xml:"public_traffic_out" json:"public_traffic_out"`
36+
StorageSize int `xml:"storage_size" json:"storage_size"`
37+
StorageTier string `xml:"storage_tier" json:"storage_tier"`
1638
}

upcloud/plan_test.go

Lines changed: 55 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,70 @@
11
package upcloud
22

33
import (
4-
"encoding/xml"
4+
"encoding/json"
55
"testing"
66

77
"github.com/stretchr/testify/assert"
88
)
99

1010
// TestUnmarshalPlans tests that Plans and Plan objects unmarshal correctly
1111
func TestUnmarshalPlans(t *testing.T) {
12-
originalXML := `<?xml version="1.0" encoding="utf-8"?>
13-
<plans>
14-
<plan>
15-
<core_number>1</core_number>
16-
<memory_amount>1024</memory_amount>
17-
<name>1xCPU-1GB</name>
18-
<public_traffic_out>2048</public_traffic_out>
19-
<storage_size>30</storage_size>
20-
<storage_tier>maxiops</storage_tier>
21-
</plan>
22-
<plan>
23-
<core_number>2</core_number>
24-
<memory_amount>2048</memory_amount>
25-
<name>2xCPU-2GB</name>
26-
<public_traffic_out>3072</public_traffic_out>
27-
<storage_size>50</storage_size>
28-
<storage_tier>maxiops</storage_tier>
29-
</plan>
30-
<plan>
31-
<core_number>4</core_number>
32-
<memory_amount>4096</memory_amount>
33-
<name>4xCPU-4GB</name>
34-
<public_traffic_out>4096</public_traffic_out>
35-
<storage_size>100</storage_size>
36-
<storage_tier>maxiops</storage_tier>
37-
</plan>
38-
<plan>
39-
<core_number>6</core_number>
40-
<memory_amount>8192</memory_amount>
41-
<name>6xCPU-8GB</name>
42-
<public_traffic_out>8192</public_traffic_out>
43-
<storage_size>200</storage_size>
44-
<storage_tier>maxiops</storage_tier>
45-
</plan>
46-
</plans>`
12+
originalJSON := `
13+
{
14+
"plans" : {
15+
"plan" : [
16+
{
17+
"core_number" : 1,
18+
"memory_amount" : 2048,
19+
"name" : "1xCPU-2GB",
20+
"public_traffic_out" : 2048,
21+
"storage_size" : 50,
22+
"storage_tier" : "maxiops"
23+
},
24+
{
25+
"core_number" : 2,
26+
"memory_amount" : 4096,
27+
"name" : "2xCPU-4GB",
28+
"public_traffic_out" : 4096,
29+
"storage_size" : 80,
30+
"storage_tier" : "maxiops"
31+
}
32+
]
33+
}
34+
}
35+
`
4736

4837
plans := Plans{}
49-
err := xml.Unmarshal([]byte(originalXML), &plans)
38+
err := json.Unmarshal([]byte(originalJSON), &plans)
5039
assert.Nil(t, err)
51-
assert.Len(t, plans.Plans, 4)
40+
assert.Len(t, plans.Plans, 2)
5241

53-
plan := plans.Plans[0]
54-
assert.Equal(t, 1, plan.CoreNumber)
55-
assert.Equal(t, 1024, plan.MemoryAmount)
56-
assert.Equal(t, "1xCPU-1GB", plan.Name)
57-
assert.Equal(t, 2048, plan.PublicTrafficOut)
58-
assert.Equal(t, 30, plan.StorageSize)
59-
assert.Equal(t, StorageTierMaxIOPS, plan.StorageTier)
42+
testData := []Plan{
43+
{
44+
CoreNumber: 1,
45+
MemoryAmount: 2048,
46+
Name: "1xCPU-2GB",
47+
PublicTrafficOut: 2048,
48+
StorageSize: 50,
49+
StorageTier: "maxiops",
50+
},
51+
{
52+
CoreNumber: 2,
53+
MemoryAmount: 4096,
54+
Name: "2xCPU-4GB",
55+
PublicTrafficOut: 4096,
56+
StorageSize: 80,
57+
StorageTier: "maxiops",
58+
},
59+
}
60+
61+
for i, p := range testData {
62+
plan := plans.Plans[i]
63+
assert.Equal(t, p.CoreNumber, plan.CoreNumber)
64+
assert.Equal(t, p.MemoryAmount, plan.MemoryAmount)
65+
assert.Equal(t, p.Name, plan.Name)
66+
assert.Equal(t, p.PublicTrafficOut, plan.PublicTrafficOut)
67+
assert.Equal(t, p.StorageSize, plan.StorageSize)
68+
assert.Equal(t, p.StorageTier, plan.StorageTier)
69+
}
6070
}

upcloud/price.go

Lines changed: 49 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,58 @@
11
package upcloud
22

3-
// PrizeZones represents a /price response
4-
type PrizeZones struct {
5-
PrizeZones []PrizeZone `xml:"zone"`
3+
import "encoding/json"
4+
5+
// PriceZones represents a /price response
6+
type PriceZones struct {
7+
PriceZones []PriceZone `xml:"prices" json:"prices"`
68
}
79

8-
// PrizeZone represents a price zone. A prize zone consists of multiple items that each have a price.
9-
type PrizeZone struct {
10-
Name string `xml:"name"`
11-
12-
Firewall *Price `xml:"firewall"`
13-
IORequestBackup *Price `xml:"io_request_backup"`
14-
IORequestMaxIOPS *Price `xml:"io_request_maxiops"`
15-
IPv4Address *Price `xml:"ipv4_address"`
16-
IPv6Address *Price `xml:"ipv6_address"`
17-
PublicIPv4BandwidthIn *Price `xml:"public_ipv4_bandwidth_in"`
18-
PublicIPv4BandwidthOut *Price `xml:"public_ipv4_bandwidth_out"`
19-
PublicIPv6BandwidthIn *Price `xml:"public_ipv6_bandwidth_in"`
20-
PublicIPv6BandwidthOut *Price `xml:"public_ipv6_bandwidth_out"`
21-
ServerCore *Price `xml:"server_core"`
22-
ServerMemory *Price `xml:"server_memory"`
23-
ServerPlan1xCPU1GB *Price `xml:"server_plan_1xCPU-1GB"`
24-
ServerPlan2xCPU2GB *Price `xml:"server_plan_2xCPU-2GB"`
25-
ServerPlan4xCPU4GB *Price `xml:"server_plan_4xCPU-4GB"`
26-
ServerPlan6xCPU8GB *Price `xml:"server_plan_6xCPU-8GB"`
27-
StorageBackup *Price `xml:"storage_backup"`
28-
StorageMaxIOPS *Price `xml:"storage_maxiops"`
29-
StorageTemplate *Price `xml:"storage_template"`
10+
// UnmarshalJSON is a custom unmarshaller that deals with
11+
// deeply embedded values.
12+
func (s *PriceZones) UnmarshalJSON(b []byte) error {
13+
type serverWrapper struct {
14+
PriceZones []PriceZone `json:"zone"`
15+
}
16+
17+
v := struct {
18+
PriceZones serverWrapper `json:"prices"`
19+
}{}
20+
err := json.Unmarshal(b, &v)
21+
if err != nil {
22+
return err
23+
}
24+
25+
s.PriceZones = v.PriceZones.PriceZones
26+
27+
return nil
28+
}
29+
30+
// PriceZone represents a price zone. A prize zone consists of multiple items that each have a price.
31+
type PriceZone struct {
32+
Name string `xml:"name" json:"name"`
33+
34+
Firewall *Price `xml:"firewall" json:"firewall"`
35+
IORequestBackup *Price `xml:"io_request_backup" json:"io_request_backup"`
36+
IORequestMaxIOPS *Price `xml:"io_request_maxiops" json:"io_request_maxiops"`
37+
IPv4Address *Price `xml:"ipv4_address" json:"ipv4_address"`
38+
IPv6Address *Price `xml:"ipv6_address" json:"ipv6_address"`
39+
PublicIPv4BandwidthIn *Price `xml:"public_ipv4_bandwidth_in" json:"public_ipv4_bandwidth_in"`
40+
PublicIPv4BandwidthOut *Price `xml:"public_ipv4_bandwidth_out" json:"public_ipv4_bandwidth_out"`
41+
PublicIPv6BandwidthIn *Price `xml:"public_ipv6_bandwidth_in" json:"public_ipv6_bandwidth_in"`
42+
PublicIPv6BandwidthOut *Price `xml:"public_ipv6_bandwidth_out" json:"public_ipv6_bandwidth_out"`
43+
ServerCore *Price `xml:"server_core" json:"server_core"`
44+
ServerMemory *Price `xml:"server_memory" json:"server_memory"`
45+
ServerPlan1xCPU1GB *Price `xml:"server_plan_1xCPU-1GB" json:"server_plan_1xCPU-1GB"`
46+
ServerPlan2xCPU2GB *Price `xml:"server_plan_2xCPU-2GB" json:"server_plan_1xCPU-2GB"`
47+
ServerPlan4xCPU4GB *Price `xml:"server_plan_4xCPU-4GB" json:"server_plan_4xCPU-4GB"`
48+
ServerPlan6xCPU8GB *Price `xml:"server_plan_6xCPU-8GB" json:"server_plan_6xCPU-8GB"`
49+
StorageBackup *Price `xml:"storage_backup" json:"storage_backup"`
50+
StorageMaxIOPS *Price `xml:"storage_maxiops" json:"storage_maxiops"`
51+
StorageTemplate *Price `xml:"storage_template" json:"storage_template"`
3052
}
3153

3254
// Price represents a price
3355
type Price struct {
34-
Amount int `xml:"amount"`
35-
Price float64 `xml:"price"`
56+
Amount int `xml:"amount" json:"amount"`
57+
Price float64 `xml:"price" json:"price"`
3658
}

0 commit comments

Comments
 (0)