File Coverage

blib/lib/Paws/Net/JsonResponse.pm
Criterion Covered Total %
statement 98 113 86.7
branch 58 74 78.3
condition 6 7 85.7
subroutine 10 10 100.0
pod 0 6 0.0
total 172 210 81.9


line stmt bran cond sub pod time code
1             package Paws::Net::JsonResponse;
2 13     13   5769 use Moose::Role;
  13         29  
  13         90  
3 13     13   62438 use JSON::MaybeXS;
  13         30  
  13         733  
4 13     13   74 use Carp qw(croak);
  13         26  
  13         512  
5 13     13   75 use Paws::Exception;
  13         22  
  13         13705  
6            
7             sub handle_response {
8 84     84 0 70854 my ($self, $call_object, $http_status, $content, $headers) = @_;
9              
10 84 100       335 if (defined $headers->{ 'x-amz-crc32' }) {
11 3         883 require String::CRC32;
12 3         1301 my $crc = String::CRC32::crc32($content);
13             return Paws::Exception->new(
14             code => 'Crc32Error',
15             message => 'Content CRC32 mismatch',
16             request_id => $headers->{ 'x-amzn-requestid' }
17 3 50       19 ) if ($crc != $headers->{ 'x-amz-crc32' });
18             }
19              
20 84 100       325 if ( $http_status >= 300 ) {
21 30         108 return $self->error_to_exception($call_object, $http_status, $content, $headers);
22             } else {
23 54         289 return $self->response_to_object($call_object, $http_status, $content, $headers);
24             }
25             }
26            
27             sub unserialize_response {
28 76     76 0 222 my ($self, $data) = @_;
29              
30 76         1132 return decode_json( $data );
31             }
32              
33             sub error_to_exception {
34 30     30 0 88 my ($self, $call_object, $http_status, $content, $headers) = @_;
35            
36 30         52 my $struct = eval { $self->unserialize_response( $content ) };
  30         86  
37 30 100       91 if ($@) {
38 12         238 return Paws::Exception->new(
39             message => $@,
40             code => 'InvalidContent',
41             request_id => '', #$request_id,
42             http_status => $http_status,
43             );
44             }
45              
46 18         39 my ($message, $request_id);
47              
48 18 100       60 if (exists $struct->{message}){
    50          
49 12         26 $message = $struct->{message};
50             } elsif (exists $struct->{Message}){
51 0         0 $message = $struct->{Message};
52             } else {
53 6         13 $message = 'Unrecognized error format';
54             }
55              
56 18   100     61 my $code = $struct->{__type} // 'InvalidContent';
57 18 100       65 if ($code =~ m/#/) {
58 2         11 $code = (split /#/, $code)[1];
59             }
60 18   50     62 $request_id = $headers->{ 'x-amzn-requestid' } // '';
61              
62 18         401 Paws::Exception->new(
63             message => $message,
64             code => $code,
65             request_id => $request_id,
66             http_status => $http_status,
67             );
68             }
69              
70             sub handle_response_strtonativemap {
71 4     4 0 19 my ($self, $att_class, $value) = @_;
72              
73 4 50       18 if (not defined $value){
74 0         0 return $att_class->new(Map => {});
75             } else {
76 4         27 return $att_class->new(Map => $value);
77             }
78             }
79              
80             sub handle_response_strtoobjmap {
81 9     9 0 34 my ($self, $att_class, $value) = @_;
82              
83 9         20 my $is_array = 0;
84 9         16 my $inner_class;
85 9         44 my $class = $att_class->meta->get_attribute('Map')->type_constraint->name;
86              
87 9 100       787 if (my ($array_type) = ($class =~ m/^HashRef\[ArrayRef\[(.*)\]\]$/)){
    50          
88 3         8 $inner_class = $array_type;
89 3         8 $is_array = 1;
90             } elsif (my ($inner_type) = ($class =~ m/^HashRef\[(.*)\]$/)) {
91 6         12 $inner_class = $inner_type;
92 6         17 $is_array = 0;
93             }
94              
95 9         45 Paws->load_class("$inner_class");
96              
97 9 100       35 if ($is_array) {
98 3 50       13 if (not defined $value){
99 0         0 return $att_class->new(Map => {});
100             } else {
101             return $att_class->new(Map => {
102 3         13 map { my $k = $_; ($k => [ map { $self->new_from_result_struct($inner_class, $_) } @{ $value->{ $k } } ] ) } keys %$value
  3         6  
  3         6  
  4         2231  
  3         9  
103             });
104             }
105             } else {
106 6 50       23 if (not defined $value){
107 0         0 return $att_class->new(Map => {});
108             } else {
109             return $att_class->new(Map => {
110 6         35 map { ($_ => $self->new_from_result_struct($inner_class, $value->{ $_ }) ) } keys %$value
  9         6905  
111             });
112             }
113             }
114             }
115              
116             sub new_from_result_struct {
117 112     112 0 434 my ($self, $class, $result) = @_;
118 112         221 my %args;
119            
120 112 100       464 if ($class->does('Paws::API::StrToObjMapParser')) {
    50          
121 2         402 return $self->handle_response_strtoobjmap($class, $result);
122             } elsif ($class->does('Paws::API::StrToNativeMapParser')) {
123 0         0 return $self->handle_response_strtonativemap($class, $result);
124             } else {
125 110         46027 foreach my $att ($class->meta->get_attribute_list) {
126 641 50       56464 next if (not my $meta = $class->meta->get_attribute($att));
127              
128 641 50       15016 my $key = $meta->does('NameInRequest') ? $meta->request_name :
    100          
129             $meta->does('ParamInHeader') ? lc($meta->header_name) : $att;
130              
131 641         113517 my $att_type = $meta->type_constraint;
132              
133             # use Data::Dumper;
134             # print STDERR "USING KEY: $key\n";
135             # print STDERR "$att IS A '$att_type' TYPE\n";
136             # print STDERR "VALUE: " . Dumper($result);
137             # my $extracted_val = $result->{ $key };
138             # print STDERR "RESULT >>> $extracted_val\n";
139              
140             # We'll consider that an attribute without brackets [] isn't an array type
141 641 100       5391 if ($att_type !~ m/\[.*\]$/) {
    100          
142 502         15930 my $value = $result->{ $key };
143 502         885 my $value_ref = ref($value);
144              
145 502 100       939 if ($att_type =~ m/\:\:/) {
146             # Make the att_type stringify for module loading
147 101         3067 Paws->load_class("$att_type");
148 101 100       367 if (defined $value) {
149 29 50       105 if (not $value_ref) {
150 0         0 $args{ $att } = $value;
151             } else {
152 29         869 my $att_class = $att_type->class;
153              
154 29 100       408 if ($att_class->does('Paws::API::StrToObjMapParser')) {
    100          
    50          
155 6         1215 $args{ $att } = $self->handle_response_strtoobjmap($att_class, $value);
156             } elsif ($att_class->does('Paws::API::StrToNativeMapParser')) {
157 4         1730 $args{ $att } = $self->handle_response_strtonativemap($att_class, $value);
158             } elsif ($att_class->does('Paws::API::MapParser')) {
159 0         0 my $xml_keys = $att_class->xml_keys;
160 0         0 my $xml_values = $att_class->xml_values;
161              
162 0         0 $args{ $att } = $att_class->new(map { ($_->{ $xml_keys } => $_->{ $xml_values }) } @$value);
  0         0  
163             } else {
164 19         12256 $args{ $att } = $self->new_from_result_struct($att_class, $value);
165             }
166             }
167             }
168             } else {
169 401 100       12270 if (defined $value) {
170 234 100       604 if ($att_type eq 'Bool') {
171 9 100       394 if ($value eq 'true') {
    50          
    0          
172 8         161 $args{ $att } = 1;
173             } elsif ($value eq 'false') {
174 1         31 $args{ $att } = 0;
175             } elsif ($value == 1) {
176 0         0 $args{ $att } = 1;
177             } else {
178 0         0 $args{ $att } = 0;
179             }
180             } else {
181 225         7083 $args{ $att } = $value;
182             }
183             }
184             }
185             } elsif (my ($type) = ($att_type =~ m/^ArrayRef\[(.*)\]$/)) {
186 107         7075 my $value = $result->{ $att };
187 107 100 100     546 $value = $result->{ $key } if (not defined $value and $key ne $att);
188 107         218 my $value_ref = ref($value);
189              
190 107 100       348 if ($type =~ m/\:\:/) {
191 63         306 Paws->load_class($type);
192              
193 63 100       457 if ($type->does('Paws::API::StrToObjMapParser')) {
    50          
    50          
194 2         389 $args{ $att } = [ map { $self->handle_response_strtoobjmap($type, $_) } @$value ];
  1         7  
195             } elsif ($type->does('Paws::API::StrToNativeMapParser')) {
196 0         0 $args{ $att } = [ map { $self->handle_response_strtonativemap($type, $_) } @$value ];
  0         0  
197             } elsif ($type->does('Paws::API::MapParser')) {
198 0         0 die "MapParser Type in an Array. Please implement me";
199             } else {
200 61         37874 $args{ $att } = [ map { $self->new_from_result_struct($type, $_) } @$value ];
  34         19492  
201             }
202             } else {
203 44 100       142 if (defined $value){
204 5         17 $args{ $att } = $value;
205             }
206             }
207             }
208             }
209 110         28234 $class->new(%args);
210             }
211             }
212             1;