File Coverage

blib/lib/Net/Gnats/Response.pm
Criterion Covered Total %
statement 92 106 86.7
branch 43 54 79.6
condition 17 21 80.9
subroutine 18 19 94.7
pod 8 10 80.0
total 178 210 84.7


line stmt bran cond sub pod time code
1             package Net::Gnats::Response;
2 40     40   21953 use v5.10.00;
  40         126  
3 40     40   976 use strictures;
  40         1725  
  40         212  
4             BEGIN {
5 40     40   9032 $Net::Gnats::Response::VERSION = '0.22';
6             }
7 40     40   200 use vars qw($VERSION);
  40         66  
  40         1542  
8              
9 40     40   1413 use Net::Gnats qw(verbose_level);
  40         72  
  40         1119  
10 40     40   20797 use Net::Gnats::Constants qw(LF CODE_TEXT_READY CODE_PR_READY);
  40         109  
  40         52814  
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 1464 my ($class, %opt) = @_;
74 571         2891 my $c = { trace => 0,
75             delim => ' ',
76             is_finished => 0,
77             content => [],
78             has_more => 0,
79             type => 0,
80             };
81 571         1169 my $self = bless $c, $class;
82              
83 571 50       1425 if (%opt) {
84 571 100       1814 $c->{type} = $opt{type} if defined $opt{type};
85 571 50       1395 $c->{code} = $opt{code} if defined $opt{code};
86 571 100 66     1684 if (defined $opt{raw} and ref $opt{raw} eq 'ARRAY') {
87 2         4 foreach my $r (@{$opt{raw}}) {
  2         6  
88 6         14 $c->raw($r);
89             }
90             }
91             }
92              
93 571         1746 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 9007 my ( $self, $value ) = @_;
114 6026         10816 _trace('start raw');
115 6026 100       15138 $self->{raw} = [] if not defined $self->{raw};
116 6026 100       12951 push @{ $self->{raw} }, $value if defined $value;
  6021         13929  
117 6026 100       18361 $self->_process_line($value) if defined $value;
118 6026 100       18275 $self->_check_finish($value) if defined $value;
119 6026         11832 _trace('end raw');
120 6026         14221 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 35674 my ( $self ) = @_;
134 28526 100       58437 if ( $self->{type} == 1 ) { return 1; }
  3         11  
135 28523         116629 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 9 my ( $self ) = @_;
146              
147 6 100       17 $self->{inner_responses} = [] if not defined $self->{inner_responses};
148 6         15 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 21824 return shift->{is_finished};
160             }
161              
162 5857     5857 0 15610 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 5227 my ($self) = @_;
197              
198             # get children lists
199 3858 100       8921 if ( $self->{type} == 1 ) {
200 3         7 my $result = [];
201 3         4 for ( @{ $self->inner_responses } ) {
  3         8  
202 3         5 push @$result, @{ $_->as_list };
  3         8  
203             }
204 3         16 return $result;
205             }
206              
207 3855         20761 return $self->{content};
208             }
209              
210             =item as_string
211              
212             =back
213              
214             =cut
215              
216             sub as_string {
217 100     100 1 207 my ( $self ) = @_;
218 100 100       337 if ( $self->{type} == 1 ) {
219 3         5 my $result = '';
220 3         6 my @responses = @{ $self->inner_responses };
  3         6  
221 3         8 my $last_response = pop @responses;
222 3         7 for ( @responses ) {
223 1         4 $result .= $_->as_string . ', ';
224             }
225 3 100       12 $result .= defined $last_response ? $last_response->as_string : '';
226 3         14 return $result;
227             }
228 97         198 return join ( $self->{delim}, @{ $self->{content} } );
  97         684  
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         4 push @{$self->{inner_responses}}, $response;
  2         5  
242 2         23 return $self;
243             }
244              
245             sub _check_finish {
246 6021     6021   8667 my ( $self, $last ) = @_;
247 6021 100 66     20736 if ( $last eq '.' and
    100 66        
    100 100        
248             ($self->code == CODE_TEXT_READY or
249             $self->code == CODE_PR_READY)) {
250 164         260 $self->{is_finished} = 1;
251 164         270 return;
252             }
253             elsif ($self->has_more == 1) {
254 3598         6594 $self->{is_finished} = 0;
255             }
256             elsif ($self->code != CODE_TEXT_READY and
257             $self->code != CODE_PR_READY) {
258 406         840 $self->{is_finished} = 1;
259             }
260             }
261              
262             sub _process_line {
263 6021     6021   8656 my ( $self, $raw ) = @_;
264 6021         10179 _trace('start _process_line');
265             #list
266 6021 100 100     12556 if ( defined $self->code and
      66        
267             ($self->code == CODE_TEXT_READY or
268             $self->code == CODE_PR_READY)) {
269 1853 100       4023 return if $raw eq '.';
270 1689         1881 push @{ $self->{content} }, $raw;
  1689         3600  
271 1689         2661 return;
272             }
273              
274             # this is a list and code has already been processed
275             #return if defined $self->code;
276 4168         20752 my @result = $raw =~ /^(\d\d\d)([- ]?)(.*$)/sxm;
277 4168         8447 $self->{code} = $result[0];
278 4168 100       10566 $self->{has_more} = 1 if $result[1] eq '-';
279 4168 100       8683 $self->{has_more} = 0 if $result[1] eq ' ';
280 4168 100 100     7931 push @{ $self->{content} }, $result[2]
  4004         9932  
281             unless ( $self->code == CODE_TEXT_READY or
282             $self->code == CODE_PR_READY );
283 4168         9883 return;
284             }
285              
286             sub _trace {
287 18073     18073   23855 my ( $message ) = @_;
288 18073 50       48144 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