File Coverage

blib/lib/Net/Gnats/Response.pm
Criterion Covered Total %
statement 93 107 86.9
branch 43 54 79.6
condition 17 21 80.9
subroutine 18 19 94.7
pod 8 10 80.0
total 179 211 84.8


line stmt bran cond sub pod time code
1             package Net::Gnats::Response;
2 40     40   17948 use v5.10.00;
  40         115  
  40         1953  
3 40     40   678 use strictures;
  40         684  
  40         218  
4             BEGIN {
5 40     40   3583 $Net::Gnats::Response::VERSION = '0.21';
6             }
7 40     40   214 use vars qw($VERSION);
  40         68  
  40         1845  
8              
9 40     40   1015 use Net::Gnats qw(verbose_level);
  40         56  
  40         1114  
10 40     40   15878 use Net::Gnats::Constants qw(LF CODE_TEXT_READY CODE_PR_READY);
  40         88  
  40         47115  
11              
12             # {
13             # my ($code, $raw, $type);
14              
15             # # internally manage type
16             # my $set_type = sub { $type = shift };
17             # my $set_code = sub {
18             # my $value = shift;
19             # $code = -1 if $value !~ /\d\d\d/;
20             # $code = $value;
21             # };
22             # my $set_raw = sub {
23             # $raw = shift;
24             # };
25             # }
26              
27             =head1 NAME
28              
29             Net::Gnats::Response - A Gnats payload class.
30              
31             =head1 DESCRIPTION
32              
33             For dealing with raw responses and error codes returned by
34             Gnatsd. Enables an easier payload method.
35              
36             =head1 VERSION
37              
38             0.15
39              
40             =head1 SYNOPSIS
41              
42             use Net::Gnats::Reponse;
43              
44             # Compose payload via constructor
45             my $response = Net::Gnats::Response->new({ raw => $data,
46             code => $code});
47              
48             # Compose disparately
49             my $response = Net::Gnats::Response->new;
50             $response->raw($data);
51             $response->code($code);
52              
53              
54             =head1 CONSTRUCTORS
55              
56             There are two types of constructors available.
57              
58             The first enables a 'shell' response which carries children responses.
59             The shell response does not require initialization data.
60              
61             The second enables the capturing a full response. When initializing
62             the response, the code and raw data must be passed to initialization.
63              
64             =head2 new
65              
66             Constructor for the shell Response object.
67              
68             my $r = new(code => $code, raw => $raw)
69              
70             =cut
71              
72             sub new {
73 571     571 1 1406 my ($class, %opt) = @_;
74 571         3170 my $c = { trace => 0,
75             delim => ' ',
76             is_finished => 0,
77             content => [],
78             has_more => 0,
79             type => 0,
80             };
81 571         1630 my $self = bless $c, $class;
82              
83 571 50       1370 if (%opt) {
84 571 100       1936 $c->{type} = $opt{type} if defined $opt{type};
85 571 50       1315 $c->{code} = $opt{code} if defined $opt{code};
86 571 100 66     1665 if (defined $opt{raw} and ref $opt{raw} eq 'ARRAY') {
87 2         3 foreach my $r (@{$opt{raw}}) {
  2         6  
88 6         10 $c->raw($r);
89             }
90             }
91             }
92              
93 571         1531 return $self;
94             }
95              
96             =head1 ACCESSORS
97              
98             The following public accessors are available. All accessors are
99             readonly because the response class expects the raw data to be
100             submitted during instantiation.
101              
102             =head2 raw
103              
104             The readonly raw accessor retrieves raw result data for this particular
105             response. If this is a parent response for a single payload, then it
106             will return an empty anonymous array.
107              
108             my $r = Net::Gnats::Response( code => $code, raw => $raw );
109              
110             =cut
111              
112             sub raw {
113 6026     6026 1 6959 my ( $self, $value ) = @_;
114 6026         9087 _trace('start raw');
115 6026 100       12614 $self->{raw} = [] if not defined $self->{raw};
116 6026 100       9650 push @{ $self->{raw} }, $value if defined $value;
  6021         12005  
117 6026 100       15839 $self->_process_line($value) if defined $value;
118 6026 100       15196 $self->_check_finish($value) if defined $value;
119 6026         8997 _trace('end raw');
120 6026         11136 return $self->{raw};
121             }
122              
123             =head2 code
124              
125             The readonly code accessor for the result code.
126              
127             my $r = Net::Gnats::Response( code => $code, raw => $raw );
128             return 1 if $r->code == Net::Gnats::CODE_OK;
129              
130             =cut
131              
132             sub code {
133 28526     28526 1 25062 my ( $self ) = @_;
134 28526 100       45219 if ( $self->{type} == 1 ) { return 1; }
  3         12  
135 28523         95285 return $self->{code};
136             }
137              
138             =head2 inner_responses
139              
140             The readonly accessor for fetching child responses.
141              
142             =cut
143              
144             sub inner_responses {
145 6     6 1 7 my ( $self ) = @_;
146              
147 6 100       21 $self->{inner_responses} = [] if not defined $self->{inner_responses};
148 6         16 return $self->{inner_responses};
149             }
150              
151             =head2 is_finished
152              
153             The response has completed processing. Returns 1 if processing has
154             completed, returns 0 otherwise.
155              
156             =cut
157              
158             sub is_finished {
159 6583     6583 1 17367 return shift->{is_finished};
160             }
161              
162 5857     5857 0 13687 sub has_more { return shift->{has_more}; }
163              
164             =head2 status
165              
166             Retrieve the overall status of the response. If this response, or all child responses,
167             resulted positively then returns 1. Otherwise, it returns 0.
168              
169             =cut
170              
171             sub status {
172 0     0 1 0 my ( $self ) = @_;
173 0 0       0 if ( $self->type == 1 ) {
174 0         0 foreach ( @{ $self->inner_responses } ) {
  0         0  
175 0 0       0 return 0 if $_->status == 0;
176             }
177 0         0 return 1;
178             }
179 0 0       0 return 0 if $self->code;
180             }
181              
182             =head1 METHODS
183              
184             =begin
185              
186             =item as_list
187              
188             Assumes the Gnatsd payload response is a 'list' and parses it as so.
189              
190             Returns: Anonymous array of list items from this response and all
191             children.
192              
193             =cut
194              
195             sub as_list {
196 3858     3858 1 4192 my ($self) = @_;
197              
198             # get children lists
199 3858 100       7024 if ( $self->{type} == 1 ) {
200 3         5 my $result = [];
201 3         3 for ( @{ $self->inner_responses } ) {
  3         7  
202 3         5 push @$result, @{ $_->as_list };
  3         13  
203             }
204 3         15 return $result;
205             }
206              
207 3855         18920 return $self->{content};
208             }
209              
210             =item as_string
211              
212             =back
213              
214             =cut
215              
216             sub as_string {
217 100     100 1 161 my ( $self ) = @_;
218 100 100       311 if ( $self->{type} == 1 ) {
219 3         5 my $result = '';
220 3         3 my @responses = @{ $self->inner_responses };
  3         7  
221 3         4 my $last_response = pop @responses;
222 3         8 for ( @responses ) {
223 1         5 $result .= $_->as_string . ', ';
224             }
225 3 100       13 $result .= defined $last_response ? $last_response->as_string : '';
226 3         12 return $result;
227             }
228 97         161 return join ( $self->{delim}, @{ $self->{content} } );
  97         553  
229             }
230              
231              
232             sub add {
233 2     2 0 4 my ( $self, $response ) = @_;
234 2 50       14 if (ref $response eq 'ARRAY') {
    50          
235 0         0 push @{$self->{inner_responses}}, @{$response};
  0         0  
  0         0  
236             }
237             elsif ( not $response->isa('Net::Gnats::Response') ) {
238 0         0 warn "you tried adding a response that's not a response! Discarded.";
239 0         0 return $self;
240             }
241 2         3 push @{$self->{inner_responses}}, $response;
  2         5  
242 2         25 return $self;
243             }
244              
245             sub _check_finish {
246 6021     6021   6762 my ( $self, $last ) = @_;
247 6021 100 66     17708 if ( $last eq '.' and
    100 66        
    100 100        
248             ($self->code == CODE_TEXT_READY or
249             $self->code == CODE_PR_READY)) {
250 164         280 $self->{is_finished} = 1;
251 164         231 return;
252             }
253             elsif ($self->has_more == 1) {
254 3598         6539 $self->{is_finished} = 0;
255             }
256             elsif ($self->code != CODE_TEXT_READY and
257             $self->code != CODE_PR_READY) {
258 406         702 $self->{is_finished} = 1;
259             }
260             }
261              
262             sub _process_line {
263 6021     6021   6696 my ( $self, $raw ) = @_;
264 6021         7755 _trace('start _process_line');
265             #list
266 6021 100 100     9462 if ( defined $self->code and
      66        
267             ($self->code == CODE_TEXT_READY or
268             $self->code == CODE_PR_READY)) {
269 1853 100       3565 return if $raw eq '.';
270 1689         1402 push @{ $self->{content} }, $raw;
  1689         2812  
271 1689         2091 return;
272             }
273              
274             # this is a list and code has already been processed
275             #return if defined $self->code;
276 4168         24569 my @result = $raw =~ /^(\d\d\d)([- ]?)(.*$)/sxm;
277 4168         7133 $self->{code} = $result[0];
278 4168 100       8419 $self->{has_more} = 1 if $result[1] eq '-';
279 4168 100       6740 $self->{has_more} = 0 if $result[1] eq ' ';
280 4168 100 100     6727 push @{ $self->{content} }, $result[2]
  4004         7792  
281             unless ( $self->code == CODE_TEXT_READY or
282             $self->code == CODE_PR_READY );
283 4168         7174 return;
284             }
285              
286             sub _trace {
287 18073     18073   18789 my ( $message ) = @_;
288 18073 50       36346 return if Net::Gnats->verbose_level() != 3;
289 0           print 'TRACE(Response): [' . $message . ']' . LF;
290 0           return;
291             }
292              
293             1;
294              
295              
296             =head1 INCOMPATIBILITIES
297              
298             None.
299              
300             =head1 SUBROUTINES/METHODS
301              
302             =over
303              
304             =head1 BUGS AND LIMITATIONS
305              
306             None.
307              
308             =head1 CONFIGURATION AND ENVIRONMENT
309              
310             None.
311              
312             =head1 DEPENDENCIES
313              
314             None.
315              
316             =head1 DIAGNOSTICS
317              
318             None.
319              
320             =head1 AUTHOR
321              
322             Richard Elberger, riche@cpan.org
323              
324             =head1 LICENSE AND COPYRIGHT
325              
326             License: GPL V3
327              
328             (c) 2014 Richard Elberger
329              
330             =cut