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             package GraphQL::MaybeTypeCheck;
2              
3 22     22   468 use 5.014;
  22         85  
4 22     22   118 use strict;
  22         50  
  22         469  
5 22     22   103 use warnings;
  22         43  
  22         562  
6              
7 22     22   11114 use Attribute::Handlers;
  22         77723  
  22         145  
8 22     22   11076 use Devel::StrictMode;
  22         8694  
  22         1167  
9 22     22   8923 use Import::Into;
  22         13386  
  22         2175  
10              
11             =head1 NAME
12              
13             GraphQL::MaybeTypeCheck - Conditional type-checking at runtime
14              
15             =head1 SYNOPSIS
16              
17             use GraphQL::MaybeTypeCheck;
18              
19             method foo(
20             $arg1 Str,
21             $arg2 Int
22             ) :ReturnType(Map[Str, Int]) {
23             # ...
24             }
25              
26             =head1 DESCRIPTION
27              
28             This module B<optionally> enables type-checking in the caller as implemented by
29             L<Function::Parameters> and L<Return::Type> depending on whether L<Devel::StrictMode>
30             is activated.
31              
32             =head3 C<Devel::StrictMode> ON
33              
34             When L<Devel::StrictMode> is active, this module will import L<Function::Parameters>
35             into the caller with its default configuration. As of writing, this includes
36             checking both argument count and type.
37              
38             When in strict mode this also C<require>s L<Return::Type> which registers the
39             C<ReturnType> attribute.
40              
41             =head3 C<Devel::StrictMode> OFF
42              
43             When strict mode is inactive this module still imports C<Function::Parameters>
44             into the caller however it sets C<fun> and C<method> to L<lax mode|Function::Parameters/function_lax> and disables
45             argument type checking.
46              
47             This also installs a no-op C<ReturnType> attribute so the existing syntax isn't
48             broken.
49              
50             =cut
51              
52             sub ReturnType : ATTR(CODE) {
53 864     864 0 4017334 my ($package, $symbol, $referent, $attr, $data) = @_;
54              
55             # If strict mode is enabled, wrap the sub so the return type is checked
56 864         1659 if (STRICT) {
57 864 50       4021 my %args = (@$data % 2) ? (scalar => @$data) : @$data;
58 864         4117 Return::Type->wrap_sub($referent, %args);
59             }
60 22     22   159 }
  22         48  
  22         115  
61              
62             sub import {
63 620 100   620   84118 return unless $_[0] eq __PACKAGE__;
64 369         1526 my $caller = caller;
65             {
66 22     22   7517 no strict 'refs';
  22         51  
  22         2901  
  369         7646  
67 369         726 push @{"${caller}::ISA"}, __PACKAGE__;
  369         5397  
68             }
69 369         1094 if (STRICT) {
70 369         3171 Function::Parameters->import::into($caller, ':strict');
71 369         357904 require Return::Type;
72             } else {
73             Function::Parameters->import::into($caller, {
74             fun => {defaults => 'function_lax', check_argument_types => 0},
75             method => {defaults => 'method_lax', check_argument_types => 0},
76             });
77             }
78             }
79              
80             1;