forked from huaweicloud/huaweicloud-sdk-go
/
results.go
134 lines (113 loc) · 3.18 KB
/
results.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package services
import (
"encoding/json"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/internal"
"github.com/gophercloud/gophercloud/pagination"
)
type serviceResult struct {
gophercloud.Result
}
// Extract interprets a GetResult, CreateResult or UpdateResult as a concrete
// Service. An error is returned if the original call or the extraction failed.
func (r serviceResult) Extract() (*Service, error) {
var s struct {
Service *Service `json:"service"`
}
err := r.ExtractInto(&s)
return s.Service, err
}
// CreateResult is the response from a Create request. Call its Extract method
// to interpret it as a Service.
type CreateResult struct {
serviceResult
}
// GetResult is the response from a Get request. Call its Extract method
// to interpret it as a Service.
type GetResult struct {
serviceResult
}
// UpdateResult is the response from an Update request. Call its Extract method
// to interpret it as a Service.
type UpdateResult struct {
serviceResult
}
// DeleteResult is the response from a Delete request. Call its ExtractErr
// method to interpret it as a Service.
type DeleteResult struct {
gophercloud.ErrResult
}
// Service represents an OpenStack Service.
type Service struct {
// ID is the unique ID of the service.
ID string `json:"id"`
// Type is the type of the service.
Name string `json:"name"`
// Type is the type of the service.
Type string `json:"type"`
// Enabled is whether or not the service is enabled.
Enabled bool `json:"enabled"`
// Links contains referencing links to the service.
Links map[string]interface{} `json:"links"`
// Extra is a collection of miscellaneous key/values.
Extra map[string]interface{} `json:"-"`
}
func (r *Service) UnmarshalJSON(b []byte) error {
type tmp Service
var s struct {
tmp
Extra map[string]interface{} `json:"extra"`
}
err := json.Unmarshal(b, &s)
if err != nil {
return err
}
*r = Service(s.tmp)
// Collect other fields and bundle them into Extra
// but only if a field titled "extra" wasn't sent.
if s.Extra != nil {
r.Extra = s.Extra
} else {
var result interface{}
err := json.Unmarshal(b, &result)
if err != nil {
return err
}
if resultMap, ok := result.(map[string]interface{}); ok {
r.Extra = internal.RemainingKeys(Service{}, resultMap)
}
}
return err
}
// ServicePage is a single page of Service results.
type ServicePage struct {
pagination.LinkedPageBase
}
// IsEmpty returns true if the ServicePage contains no results.
func (p ServicePage) IsEmpty() (bool, error) {
services, err := ExtractServices(p)
return len(services) == 0, err
}
// NextPageURL extracts the "next" link from the links section of the result.
func (r ServicePage) NextPageURL() (string, error) {
var s struct {
Links struct {
Next string `json:"next"`
Previous string `json:"previous"`
} `json:"links"`
}
err := r.ExtractInto(&s)
if err != nil {
return "", err
}
return s.Links.Next, err
}
// ExtractServices extracts a slice of Services from a Collection acquired
// from List.
func ExtractServices(r pagination.Page) ([]Service, error) {
var s struct {
Services []Service `json:"services"`
}
err := (r.(ServicePage)).ExtractInto(&s)
return s.Services, err
}