Updated to replace httpadapter with faraday.
[arvados.git] / lib / google / api_client / result.rb
1 # Copyright 2010 Google Inc.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #      http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15
16 module Google
17   class APIClient
18     ##
19     # This class wraps a result returned by an API call.
20     class Result
21       def initialize(reference, request, response)
22         @reference = reference
23         @request = request
24         @response = response
25       end
26
27       attr_reader :reference
28
29       attr_reader :request
30
31       attr_reader :response
32
33       def status
34         return @response.status
35       end
36
37       def headers
38         return @response.headers
39       end
40
41       def body
42         return @response.body
43       end
44
45       def data
46         return @data ||= (begin
47           _, content_type = self.headers.detect do |h, v|
48             h.downcase == 'Content-Type'.downcase
49           end
50           media_type = content_type[/^([^;]*);?.*$/, 1].strip.downcase
51           data = self.body
52           case media_type
53           when 'application/json'
54             data = MultiJson.decode(data)
55             # Strip data wrapper, if present
56             data = data['data'] if data.has_key?('data')
57           else
58             raise ArgumentError,
59               "Content-Type not supported for parsing: #{media_type}"
60           end
61           if @reference.api_method && @reference.api_method.response_schema
62             # Automatically parse using the schema designated for the
63             # response of this API method.
64             data = @reference.api_method.response_schema.new(data)
65             data
66           else
67             # Otherwise, return the raw unparsed value.
68             # This value must be indexable like a Hash.
69             data
70           end
71         end)
72       end
73
74       def pagination_type
75         return :token
76       end
77
78       def page_token_param
79         return "pageToken"
80       end
81
82       def next_page_token
83         if self.data.respond_to?(:next_page_token)
84           return self.data.next_page_token
85         elsif self.data.respond_to?(:[])
86           return self.data["nextPageToken"]
87         else
88           raise TypeError, "Data object did not respond to #next_page_token."
89         end
90       end
91
92       def next_page
93         merged_parameters = Hash[self.reference.parameters].merge({
94           self.page_token_param => self.next_page_token
95         })
96         # Because References can be coerced to Hashes, we can merge them,
97         # preserving all context except the API method parameters that we're
98         # using for pagination.
99         return Google::APIClient::Reference.new(
100           Hash[self.reference].merge(:parameters => merged_parameters)
101         )
102       end
103
104       def prev_page_token
105         if self.data.respond_to?(:prev_page_token)
106           return self.data.prev_page_token
107         elsif self.data.respond_to?(:[])
108           return self.data["prevPageToken"]
109         else
110           raise TypeError, "Data object did not respond to #next_page_token."
111         end
112       end
113
114       def prev_page
115         merged_parameters = Hash[self.reference.parameters].merge({
116           self.page_token_param => self.prev_page_token
117         })
118         # Because References can be coerced to Hashes, we can merge them,
119         # preserving all context except the API method parameters that we're
120         # using for pagination.
121         return Google::APIClient::Reference.new(
122           Hash[self.reference].merge(:parameters => merged_parameters)
123         )
124       end
125     end
126   end
127 end