File Coverage

blib/lib/GraphQL/MaybeTypeCheck.pm
Criterion Covered Total %
statement 35 35 100.0
branch 3 4 75.0
condition n/a
subroutine 10 10 100.0
pod 0 1 0.0
total 48 50 96.0


line stmt bran cond sub pod time code
1              
2             use 5.014;
3 22     22   443 use strict;
  22         72  
4 22     22   108 use warnings;
  22         52  
  22         416  
5 22     22   92  
  22         36  
  22         538  
6             use Attribute::Handlers;
7 22     22   10009 use Devel::StrictMode;
  22         69273  
  22         139  
8 22     22   9510 use Import::Into;
  22         7635  
  22         1082  
9 22     22   7949  
  22         11713  
  22         1916  
10             =head1 NAME
11              
12             GraphQL::MaybeTypeCheck - Conditional type-checking at runtime
13              
14             =head1 SYNOPSIS
15              
16             use GraphQL::MaybeTypeCheck;
17              
18             method foo(
19             $arg1 Str,
20             $arg2 Int
21             ) :ReturnType(Map[Str, Int]) {
22             # ...
23             }
24              
25             =head1 DESCRIPTION
26              
27             This module B<optionally> enables type-checking in the caller as implemented by
28             L<Function::Parameters> and L<Return::Type> depending on whether L<Devel::StrictMode>
29             is activated.
30              
31             =head3 C<Devel::StrictMode> ON
32              
33             When L<Devel::StrictMode> is active, this module will import L<Function::Parameters>
34             into the caller with its default configuration. As of writing, this includes
35             checking both argument count and type.
36              
37             When in strict mode this also C<require>s L<Return::Type> which registers the
38             C<ReturnType> attribute.
39              
40             =head3 C<Devel::StrictMode> OFF
41              
42             When strict mode is inactive this module still imports C<Function::Parameters>
43             into the caller however it sets C<fun> and C<method> to L<lax mode|Function::Parameters/function_lax> and disables
44             argument type checking.
45              
46             This also installs a no-op C<ReturnType> attribute so the existing syntax isn't
47             broken.
48              
49             =cut
50              
51             my ($package, $symbol, $referent, $attr, $data) = @_;
52              
53 864     864 0 3414862 # If strict mode is enabled, wrap the sub so the return type is checked
54             if (STRICT) {
55             my %args = (@$data % 2) ? (scalar => @$data) : @$data;
56 864         1588 Return::Type->wrap_sub($referent, %args);
57 864 50       3743 }
58 864         3782 }
59              
60 22     22   168 return unless $_[0] eq __PACKAGE__;
  22         50  
  22         131  
61             my $caller = caller;
62             {
63 620 100   620   71074 no strict 'refs';
64 369         1550 push @{"${caller}::ISA"}, __PACKAGE__;
65             }
66 22     22   6794 if (STRICT) {
  22         47  
  22         2531  
  369         6982  
67 369         590 Function::Parameters->import::into($caller, ':strict');
  369         5247  
68             require Return::Type;
69 369         1001 } else {
70 369         2958 Function::Parameters->import::into($caller, {
71 369         321010 fun => {defaults => 'function_lax', check_argument_types => 0},
72             method => {defaults => 'method_lax', check_argument_types => 0},
73             });
74             }
75             }
76              
77             1;