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