File Coverage

blib/lib/JSON/RPC/Common/Procedure/Call.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1             #!/usr/bin/perl
2              
3             package JSON::RPC::Common::Procedure::Call;
4             $JSON::RPC::Common::Procedure::Call::VERSION = '0.11';
5 4     4   120334 use Moose;
  0            
  0            
6             # ABSTRACT: JSON RPC Procedure Call base class.
7              
8             use Try::Tiny;
9             use JSON::RPC::Common::TypeConstraints qw(JSONValue);
10             use JSON::RPC::Common::Procedure::Return;
11              
12             use Carp qw(croak);
13              
14             use namespace::clean -except => [qw(meta)];
15              
16             with qw(JSON::RPC::Common::Message);
17              
18             has return_class => (
19             isa => "ClassName",
20             is => "rw",
21             default => "JSON::RPC::Common::Procedure::Return",
22             );
23              
24             has error_class => (
25             isa => "ClassName",
26             is => "rw",
27             default => "JSON::RPC::Common::Procedure::Return::Error",
28             );
29              
30             has version => (
31             isa => "Str",
32             is => "rw",
33             predicate => "has_version",
34             );
35              
36             has method => (
37             isa => "Str",
38             is => "rw",
39             required => 1,
40             );
41              
42             has id => (
43             isa => JSONValue,
44             is => "rw",
45             predicate => "has_id",
46             );
47              
48             has params => (
49             isa => "Ref",
50             is => "rw",
51             predicate => "has_params",
52             );
53              
54             sub deflate_version {
55             return ();
56             }
57             sub deflate_method {
58             my $self = shift;
59             return ( method => $self->method );
60             }
61              
62             sub deflate_id {
63             my $self = shift;
64              
65             if ( $self->has_id ) {
66             return ( id => $self->id );
67             } else {
68             return ();
69             }
70             }
71              
72             sub deflate_params {
73             my $self = shift;
74              
75             if ( $self->has_params ) {
76             return ( params => $self->params );
77             } else {
78             return ();
79             }
80             }
81              
82             sub deflate {
83             my $self = shift;
84              
85             return {
86             $self->deflate_version,
87             $self->deflate_method,
88             $self->deflate_id,
89             $self->deflate_params,
90             };
91             }
92              
93             sub is_service { 0 }
94              
95             sub is_notification {
96             my $self = shift;
97             return not $self->has_id;
98             }
99              
100             sub params_list {
101             my $self = shift;
102             my $p = $self->params;
103              
104             if ( ref $p eq 'HASH' ) {
105             return %$p;
106             } elsif ( ref $p eq 'ARRAY' ) {
107             return @$p;
108             } else {
109             return $p; # FIXME error?
110             }
111             }
112              
113             sub call {
114             my ( $self, $invocant, @args ) = @_;
115              
116             die "No invocant provided" unless blessed($invocant);
117              
118             my $method = $self->method;
119              
120             my $error;
121             my @res = try {
122             $invocant->$method( $self->params_list, @args )
123             } catch {
124             $error = $_;
125             };
126              
127             if ($error) {
128             $self->return_error(message => $error);
129             }
130             else {
131             $self->return_result(@res);
132             }
133             }
134              
135             sub create_return {
136             my ( $self, @args ) = @_;
137              
138             $self->return_class->new(
139             error_class => $self->error_class,
140             ( $self->has_id ? ( id => $self->id ) : () ),
141             @args,
142             );
143             }
144              
145             sub return_error {
146             my ( $self, @args ) = @_;
147              
148             $self->create_return( error => $self->error_class->new_dwim(@args) );
149             }
150              
151             sub return_result {
152             my ( $self, @res ) = @_;
153              
154             my $res = @res == 1 ? $res[0] : \@res;
155              
156             $self->create_return( result => $res );
157             }
158              
159             __PACKAGE__->meta->make_immutable;
160              
161             __PACKAGE__
162              
163             __END__
164              
165             =pod
166              
167             =head1 NAME
168              
169             JSON::RPC::Common::Procedure::Call - JSON RPC Procedure Call base class.
170              
171             =head1 VERSION
172              
173             version 0.11
174              
175             =head1 SYNOPSIS
176              
177             use JSON::RPC::Common::Procedure::Call;
178              
179             my $req = JSON::RPC::Common::Procedure::Call->inflate({ ... });
180              
181             warn "HALLO JSONRPC VERSION " . $req->version;
182              
183             =head1 DESCRIPTION
184              
185             A JSON-RPC Procedure Call (ed: *rolls eys*, what was wrong with "request"?) is
186             either a notification or a method invocation in JSON-PRC.
187              
188             See L<http://json-rpc.org/wiki/specification> for more details.
189              
190             =head1 ATTRIBUTES
191              
192             All attributes are read only unless otherwise specified.
193              
194             =over 4
195              
196             =item version
197              
198             =item id
199              
200             The request ID.
201              
202             Used to correlate a request to a response.
203              
204             =item method
205              
206             The name of the method to invoke.
207              
208             =item params
209              
210             Returns a reference to the parameters hash or array.
211              
212             =item return_class
213              
214             =item error_class
215              
216             The classes to instantiate the response objects.
217              
218             These vary per subclass.
219              
220             =back
221              
222             =head1 METHODS
223              
224             =over 4
225              
226             =item inflate
227              
228             A factory constructor. Delegates to C<new> on a subclass based on the protocol
229             version.
230              
231             This is the recommended constructor.
232              
233             =item deflate
234              
235             Flatten to JSON data
236              
237             =item new
238              
239             The actual constructor.
240              
241             Not intended for normal use on this class, you should use a subclass most of
242             the time.
243              
244             Calling C<< JSON::RPC::Common::Procedure::Call->new >> will construct a call
245             with an undefined version, which cannot be deflated (and thus sent over the
246             wire). This is still useful for testing your own code's RPC hanlding, so this
247             is not allowed.
248              
249             =item params_list
250              
251             Dereferences C<params> regardless of representation.
252              
253             Returns a list of positionals or a key/value list.
254              
255             =item return_result $result
256              
257             =item return_error %error_params
258              
259             Create a new L<JSON::RPC::Common::Procedure::Return> with or without an error.
260              
261             =item is_notification
262              
263             Whether this request is a notification (a method that does not need a response).
264              
265             =item is_service
266              
267             Whether this request is a JSON-RPC 1.1 service method (e.g.
268             C<system.describe>).
269              
270             This method is always false for 1.0 and 2.0.
271              
272             =item call $obj
273              
274             A convenience method to invoke the call on C<$obj> and create a new return with
275             the return value.
276              
277             =back
278              
279             =head1 AUTHOR
280              
281             Yuval Kogman <nothingmuch@woobling.org>
282              
283             =head1 COPYRIGHT AND LICENSE
284              
285             This software is copyright (c) 2014 by Yuval Kogman and others.
286              
287             This is free software; you can redistribute it and/or modify it under
288             the same terms as the Perl 5 programming language system itself.
289              
290             =cut