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   5417 use Moose::Role;
  13         30  
  13         72  
3 13     13   56597 use JSON::MaybeXS;
  13         28  
  13         649  
4 13     13   74 use Carp qw(croak);
  13         26  
  13         498  
5 13     13   69 use Paws::Exception;
  13         25  
  13         13589  
6            
7             sub handle_response {
8 84     84 0 71166 my ($self, $call_object, $http_status, $content, $headers) = @_;
9              
10 84 100       300 if (defined $headers->{ 'x-amz-crc32' }) {
11 3         1158 require String::CRC32;
12 3         1559 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       16 ) if ($crc != $headers->{ 'x-amz-crc32' });
18             }
19              
20 84 100       278 if ( $http_status >= 300 ) {
21 30         101 return $self->error_to_exception($call_object, $http_status, $content, $headers);
22             } else {
23 54         256 return $self->response_to_object($call_object, $http_status, $content, $headers);
24             }
25             }
26            
27             sub unserialize_response {
28 76     76 0 210 my ($self, $data) = @_;
29              
30 76         1024 return decode_json( $data );
31             }
32              
33             sub error_to_exception {
34 30     30 0 73 my ($self, $call_object, $http_status, $content, $headers) = @_;
35            
36 30         56 my $struct = eval { $self->unserialize_response( $content ) };
  30         76  
37 30 100       86 if ($@) {
38 12         188 return Paws::Exception->new(
39             message => $@,
40             code => 'InvalidContent',
41             request_id => '', #$request_id,
42             http_status => $http_status,
43             );
44             }
45              
46 18         33 my ($message, $request_id);
47              
48 18 100       48 if (exists $struct->{message}){
    50          
49 12         24 $message = $struct->{message};
50             } elsif (exists $struct->{Message}){
51 0         0 $message = $struct->{Message};
52             } else {
53 6         9 $message = 'Unrecognized error format';
54             }
55              
56 18   100     57 my $code = $struct->{__type} // 'InvalidContent';
57 18 100       63 if ($code =~ m/#/) {
58 2         11 $code = (split /#/, $code)[1];
59             }
60 18   50     48 $request_id = $headers->{ 'x-amzn-requestid' } // '';
61              
62 18         388 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 13 my ($self, $att_class, $value) = @_;
72              
73 4 50       15 if (not defined $value){
74 0         0 return $att_class->new(Map => {});
75             } else {
76 4         24 return $att_class->new(Map => $value);
77             }
78             }
79              
80             sub handle_response_strtoobjmap {
81 9     9 0 29 my ($self, $att_class, $value) = @_;
82              
83 9         18 my $is_array = 0;
84 9         16 my $inner_class;
85 9         42 my $class = $att_class->meta->get_attribute('Map')->type_constraint->name;
86              
87 9 100       775 if (my ($array_type) = ($class =~ m/^HashRef\[ArrayRef\[(.*)\]\]$/)){
    50          
88 3         6 $inner_class = $array_type;
89 3         6 $is_array = 1;
90             } elsif (my ($inner_type) = ($class =~ m/^HashRef\[(.*)\]$/)) {
91 6         13 $inner_class = $inner_type;
92 6         11 $is_array = 0;
93             }
94              
95 9         45 Paws->load_class("$inner_class");
96              
97 9 100       32 if ($is_array) {
98 3 50       11 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         8  
  3         6  
  4         2068  
  3         7  
103             });
104             }
105             } else {
106 6 50       22 if (not defined $value){
107 0         0 return $att_class->new(Map => {});
108             } else {
109             return $att_class->new(Map => {
110 6         29 map { ($_ => $self->new_from_result_struct($inner_class, $value->{ $_ }) ) } keys %$value
  9         7286  
111             });
112             }
113             }
114             }
115              
116             sub new_from_result_struct {
117 112     112 0 396 my ($self, $class, $result) = @_;
118 112         203 my %args;
119            
120 112 100       448 if ($class->does('Paws::API::StrToObjMapParser')) {
    50          
121 2         396 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         43792 foreach my $att ($class->meta->get_attribute_list) {
126 641 50       57490 next if (not my $meta = $class->meta->get_attribute($att));
127              
128 641 50       14423 my $key = $meta->does('NameInRequest') ? $meta->request_name :
    100          
129             $meta->does('ParamInHeader') ? lc($meta->header_name) : $att;
130              
131 641         108531 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       4974 if ($att_type !~ m/\[.*\]$/) {
    100          
142 502         15487 my $value = $result->{ $key };
143 502         825 my $value_ref = ref($value);
144              
145 502 100       962 if ($att_type =~ m/\:\:/) {
146             # Make the att_type stringify for module loading
147 101         2967 Paws->load_class("$att_type");
148 101 100       354 if (defined $value) {
149 29 50       98 if (not $value_ref) {
150 0         0 $args{ $att } = $value;
151             } else {
152 29         851 my $att_class = $att_type->class;
153              
154 29 100       429 if ($att_class->does('Paws::API::StrToObjMapParser')) {
    100          
    50          
155 6         1121 $args{ $att } = $self->handle_response_strtoobjmap($att_class, $value);
156             } elsif ($att_class->does('Paws::API::StrToNativeMapParser')) {
157 4         1734 $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         11211 $args{ $att } = $self->new_from_result_struct($att_class, $value);
165             }
166             }
167             }
168             } else {
169 401 100       11755 if (defined $value) {
170 234 100       556 if ($att_type eq 'Bool') {
171 9 100       410 if ($value eq 'true') {
    50          
    0          
172 8         137 $args{ $att } = 1;
173             } elsif ($value eq 'false') {
174 1         36 $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         6740 $args{ $att } = $value;
182             }
183             }
184             }
185             } elsif (my ($type) = ($att_type =~ m/^ArrayRef\[(.*)\]$/)) {
186 107         6675 my $value = $result->{ $att };
187 107 100 100     491 $value = $result->{ $key } if (not defined $value and $key ne $att);
188 107         214 my $value_ref = ref($value);
189              
190 107 100       307 if ($type =~ m/\:\:/) {
191 63         235 Paws->load_class($type);
192              
193 63 100       389 if ($type->does('Paws::API::StrToObjMapParser')) {
    50          
    50          
194 2         403 $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         35750 $args{ $att } = [ map { $self->new_from_result_struct($type, $_) } @$value ];
  34         17991  
201             }
202             } else {
203 44 100       133 if (defined $value){
204 5         16 $args{ $att } = $value;
205             }
206             }
207             }
208             }
209 110         23572 $class->new(%args);
210             }
211             }
212             1;