blob: 3fd50296f3815d4861b908a1bace3b2e847c6d4d [file] [log] [blame]
Jamie Hannaford4baa1232014-09-23 15:23:04 +02001package gophercloud
Jamie Hannafordb3120f52014-09-23 15:17:57 +02002
Ash Wilsone8192ac2014-10-21 09:02:01 -04003import (
4 "encoding/json"
5 "net/http"
6)
Ash Wilsoneab6a702014-10-20 08:18:30 -04007
Ash Wilson3ce1bd82014-10-31 12:20:00 -04008/*
Ash Wilson64ba49f2014-10-31 15:31:46 -04009Result is an internal type to be used by individual resource packages, but its
10methods will be available on a wide variety of user-facing embedding types.
Ash Wilson3ce1bd82014-10-31 12:20:00 -040011
12It acts as a base struct that other Result types, returned from request
13functions, can embed for convenience. All Results capture basic information
14from the HTTP transaction that was performed, including the response body,
15HTTP headers, and any errors that happened.
16
17Generally, each Result type will have an Extract method that can be used to
18further interpret the result's payload in a specific context. Extensions or
19providers can then provide additional extraction functions to pull out
20provider- or extension-specific information as well.
21*/
Ash Wilsoneab6a702014-10-20 08:18:30 -040022type Result struct {
Ash Wilson3ce1bd82014-10-31 12:20:00 -040023 // Body is the payload of the HTTP response from the server. In most cases,
24 // this will be the deserialized JSON structure.
Ash Wilsond3dc2542014-10-20 10:10:48 -040025 Body interface{}
Ash Wilsoneab6a702014-10-20 08:18:30 -040026
Ash Wilson72e4d2c2014-10-20 10:27:30 -040027 // Header contains the HTTP header structure from the original response.
28 Header http.Header
Ash Wilsoneab6a702014-10-20 08:18:30 -040029
Ash Wilson3ce1bd82014-10-31 12:20:00 -040030 // Err is an error that occurred during the operation. It's deferred until
31 // extraction to make it easier to chain the Extract call.
Ash Wilsoneab6a702014-10-20 08:18:30 -040032 Err error
Jamie Hannafordb3120f52014-09-23 15:17:57 +020033}
Ash Wilsona6b08312014-10-02 15:27:45 -040034
Ash Wilson3ce1bd82014-10-31 12:20:00 -040035// PrettyPrintJSON creates a string containing the full response body as
36// pretty-printed JSON. It's useful for capturing test fixtures and for
Ash Wilson0fe6c962014-10-31 15:34:24 -040037// debugging extraction bugs. If you include its output in an issue related to
38// a buggy extraction function, we will all love you forever.
Ash Wilsone8192ac2014-10-21 09:02:01 -040039func (r Result) PrettyPrintJSON() string {
40 pretty, err := json.MarshalIndent(r.Body, "", " ")
41 if err != nil {
42 panic(err.Error())
43 }
44 return string(pretty)
45}
46
Ash Wilson64ba49f2014-10-31 15:31:46 -040047// ErrResult is an internal type to be used by individual resource packages, but
48// its methods will be available on a wide variety of user-facing embedding
49// types.
50//
51// It represents results that only contain a potential error and
Ash Wilson3ce1bd82014-10-31 12:20:00 -040052// nothing else. Usually, if the operation executed successfully, the Err field
53// will be nil; otherwise it will be stocked with a relevant error. Use the
Ash Wilson64ba49f2014-10-31 15:31:46 -040054// ExtractErr method
55// to cleanly pull it out.
Jon Perrittba2395e2014-10-27 15:23:21 -050056type ErrResult struct {
Jon Perritt0c2b0372014-10-27 15:57:29 -050057 Result
Jamie Hannaford021b35c2014-10-27 14:01:53 +010058}
59
Ash Wilson3ce1bd82014-10-31 12:20:00 -040060// ExtractErr is a function that extracts error information, or nil, from a result.
Jon Perrittba2395e2014-10-27 15:23:21 -050061func (r ErrResult) ExtractErr() error {
Jamie Hannaford021b35c2014-10-27 14:01:53 +010062 return r.Err
63}
64
Ash Wilson3ce1bd82014-10-31 12:20:00 -040065/*
Ash Wilson64ba49f2014-10-31 15:31:46 -040066HeaderResult is an internal type to be used by individual resource packages, but
67its methods will be available on a wide variety of user-facing embedding types.
Ash Wilson3ce1bd82014-10-31 12:20:00 -040068
69It represents a result that only contains an error (possibly nil) and an
70http.Header. This is used, for example, by the objectstorage packages in
71openstack, because most of the operations don't return response bodies, but do
72have relevant information in headers.
73*/
Jon Perrittd50f93e2014-10-27 14:19:27 -050074type HeaderResult struct {
Jon Perritt0c2b0372014-10-27 15:57:29 -050075 Result
Jon Perrittd50f93e2014-10-27 14:19:27 -050076}
77
78// ExtractHeader will return the http.Header and error from the HeaderResult.
Ash Wilson3ce1bd82014-10-31 12:20:00 -040079//
80// header, err := objects.Create(client, "my_container", objects.CreateOpts{}).ExtractHeader()
Jon Perrittd50f93e2014-10-27 14:19:27 -050081func (hr HeaderResult) ExtractHeader() (http.Header, error) {
82 return hr.Header, hr.Err
83}
84
Ash Wilson3ce1bd82014-10-31 12:20:00 -040085// RFC3339Milli describes a common time format used by some API responses.
Ash Wilsona6b08312014-10-02 15:27:45 -040086const RFC3339Milli = "2006-01-02T15:04:05.999999Z"
Jamie Hannaford369c9c62014-10-08 15:14:43 +020087
Ash Wilson3ce1bd82014-10-31 12:20:00 -040088/*
89Link is an internal type to be used in packages of collection resources that are
90paginated in a certain way.
91
92It's a response substructure common to many paginated collection results that is
93used to point to related pages. Usually, the one we care about is the one with
94Rel field set to "next".
95*/
Jamie Hannaford369c9c62014-10-08 15:14:43 +020096type Link struct {
97 Href string `mapstructure:"href"`
98 Rel string `mapstructure:"rel"`
99}
100
Ash Wilson3ce1bd82014-10-31 12:20:00 -0400101/*
102ExtractNextURL is an internal function useful for packages of collection
103resources that are paginated in a certain way.
104
105It attempts attempts to extract the "next" URL from slice of Link structs, or
106"" if no such URL is present.
107*/
Jamie Hannaford369c9c62014-10-08 15:14:43 +0200108func ExtractNextURL(links []Link) (string, error) {
109 var url string
110
111 for _, l := range links {
112 if l.Rel == "next" {
113 url = l.Href
114 }
115 }
116
117 if url == "" {
118 return "", nil
119 }
120
121 return url, nil
122}