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   578 use 5.014;
  22         82  
4 22     22   116 use strict;
  22         46  
  22         489  
5 22     22   103 use warnings;
  22         41  
  22         652  
6              
7 22     22   12253 use Attribute::Handlers;
  22         78148  
  22         127  
8 22     22   11951 use Devel::StrictMode;
  22         8564  
  22         1236  
9 22     22   8752 use Import::Into;
  22         12788  
  22         2170  
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 3840736 my ($package, $symbol, $referent, $attr, $data) = @_;
54              
55             # If strict mode is enabled, wrap the sub so the return type is checked
56 864         1788 if (STRICT) {
57 864 50       4450 my %args = (@$data % 2) ? (scalar => @$data) : @$data;
58 864         4272 Return::Type->wrap_sub($referent, %args);
59             }
60 22     22   157 }
  22         47  
  22         124  
61              
62             sub import {
63 620 100   620   74923 return unless $_[0] eq __PACKAGE__;
64 369         1877 my $caller = caller;
65             {
66 22     22   7245 no strict 'refs';
  22         50  
  22         2919  
  369         8108  
67 369         721 push @{"${caller}::ISA"}, __PACKAGE__;
  369         6283  
68             }
69 369         1150 if (STRICT) {
70 369         3537 Function::Parameters->import::into($caller, ':strict');
71 369         359973 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;