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   17204 use v5.10.00;
  40         100  
  40         1686  
3 40     40   665 use strictures;
  40         748  
  40         198  
4             BEGIN {
5 40     40   3110 $Net::Gnats::Response::VERSION = '0.20';
6             }
7 40     40   186 use vars qw($VERSION);
  40         59  
  40         1907  
8              
9 40     40   994 use Net::Gnats qw(verbose_level);
  40         83  
  40         948  
10 40     40   14809 use Net::Gnats::Constants qw(LF CODE_TEXT_READY CODE_PR_READY);
  40         68  
  40         41955  
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 565     565 1 1279 my ($class, %opt) = @_;
74 565         3156 my $c = { trace => 0,
75             delim => ' ',
76             is_finished => 0,
77             content => [],
78             has_more => 0,
79             type => 0,
80             };
81 565         1389 my $self = bless $c, $class;
82              
83 565 50       1240 if (%opt) {
84 565 100       1957 $c->{type} = $opt{type} if defined $opt{type};
85 565 50       1168 $c->{code} = $opt{code} if defined $opt{code};
86 565 100 66     1489 if (defined $opt{raw} and ref $opt{raw} eq 'ARRAY') {
87 2         1 foreach my $r (@{$opt{raw}}) {
  2         6  
88 6         8 $c->raw($r);
89             }
90             }
91             }
92              
93 565         1416 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 5994     5994 1 6290 my ( $self, $value ) = @_;
114 5994         9380 _trace('start raw');
115 5994 100       11561 $self->{raw} = [] if not defined $self->{raw};
116 5994 100       9446 push @{ $self->{raw} }, $value if defined $value;
  5989         10136  
117 5994 100       13727 $self->_process_line($value) if defined $value;
118 5994 100       13487 $self->_check_finish($value) if defined $value;
119 5994         8284 _trace('end raw');
120 5994         10101 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 28350     28350 1 23953 my ( $self ) = @_;
134 28350 100       41806 if ( $self->{type} == 1 ) { return 1; }
  3         13  
135 28347         84851 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 6545     6545 1 18015 return shift->{is_finished};
160             }
161              
162 5826     5826 0 11098 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 3857     3857 1 3695 my ($self) = @_;
197              
198             # get children lists
199 3857 100       7571 if ( $self->{type} == 1 ) {
200 3         6 my $result = [];
201 3         4 for ( @{ $self->inner_responses } ) {
  3         7  
202 3         4 push @$result, @{ $_->as_list };
  3         13  
203             }
204 3         13 return $result;
205             }
206              
207 3854         14264 return $self->{content};
208             }
209              
210             =item as_string
211              
212             =back
213              
214             =cut
215              
216             sub as_string {
217 100     100 1 143 my ( $self ) = @_;
218 100 100       287 if ( $self->{type} == 1 ) {
219 3         3 my $result = '';
220 3         3 my @responses = @{ $self->inner_responses };
  3         7  
221 3         4 my $last_response = pop @responses;
222 3         6 for ( @responses ) {
223 1         3 $result .= $_->as_string . ', ';
224             }
225 3 100       12 $result .= defined $last_response ? $last_response->as_string : '';
226 3         15 return $result;
227             }
228 97         148 return join ( $self->{delim}, @{ $self->{content} } );
  97         526  
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         4  
242 2         23 return $self;
243             }
244              
245             sub _check_finish {
246 5989     5989   6152 my ( $self, $last ) = @_;
247 5989 100 66     16371 if ( $last eq '.' and
    100 66        
    100 100        
248             ($self->code == CODE_TEXT_READY or
249             $self->code == CODE_PR_READY)) {
250 163         221 $self->{is_finished} = 1;
251 163         188 return;
252             }
253             elsif ($self->has_more == 1) {
254 3598         4841 $self->{is_finished} = 0;
255             }
256             elsif ($self->code != CODE_TEXT_READY and
257             $self->code != CODE_PR_READY) {
258 401         647 $self->{is_finished} = 1;
259             }
260             }
261              
262             sub _process_line {
263 5989     5989   6051 my ( $self, $raw ) = @_;
264 5989         6882 _trace('start _process_line');
265             #list
266 5989 100 100     8677 if ( defined $self->code and
      66        
267             ($self->code == CODE_TEXT_READY or
268             $self->code == CODE_PR_READY)) {
269 1827 100       2861 return if $raw eq '.';
270 1664         1299 push @{ $self->{content} }, $raw;
  1664         2478  
271 1664         1808 return;
272             }
273              
274             # this is a list and code has already been processed
275             #return if defined $self->code;
276 4162         24081 my @result = $raw =~ /^(\d\d\d)([- ]?)(.*$)/sxm;
277 4162         6398 $self->{code} = $result[0];
278 4162 100       7894 $self->{has_more} = 1 if $result[1] eq '-';
279 4162 100       6177 $self->{has_more} = 0 if $result[1] eq ' ';
280 4162 100 100     5894 push @{ $self->{content} }, $result[2]
  3999         6729  
281             unless ( $self->code == CODE_TEXT_READY or
282             $self->code == CODE_PR_READY );
283 4162         6403 return;
284             }
285              
286             sub _trace {
287 17977     17977   16401 my ( $message ) = @_;
288 17977 50       32360 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