File Coverage

blib/lib/Data/Rx/Type/Perl/Code.pm
Criterion Covered Total %
statement 29 31 93.5
branch 10 12 83.3
condition 4 5 80.0
subroutine 8 8 100.0
pod 0 3 0.0
total 51 59 86.4


line stmt bran cond sub pod time code
1 1     1   6 use strict;
  1         1  
  1         24  
2 1     1   4 use warnings;
  1         1  
  1         36  
3             package Data::Rx::Type::Perl::Code 0.010;
4             # ABSTRACT: experimental / perl coderef type
5 1     1   4 use parent 'Data::Rx::CommonType::EasyNew';
  1         2  
  1         5  
6              
7             #pod =head1 SYNOPSIS
8             #pod
9             #pod use Data::Rx;
10             #pod use Data::Rx::Type::Perl::Code;
11             #pod use Test::More tests => 2;
12             #pod
13             #pod my $rx = Data::Rx->new({
14             #pod prefix => {
15             #pod perl => 'tag:codesimply.com,2008:rx/perl/',
16             #pod },
17             #pod type_plugins => [ 'Data::Rx::Type::Perl::Code' ]
18             #pod });
19             #pod
20             #pod my $is_code = $rx->make_schema({
21             #pod type => '/perl/code',
22             #pod });
23             #pod
24             #pod ok($is_code->check( sub {} ), "a coderef is code");
25             #pod ok(! $is_code->check( 1 ), "1 is not code");
26             #pod
27             #pod =head1 ARGUMENTS
28             #pod
29             #pod If given, the C argument will require that the code has the given
30             #pod prototype.
31             #pod
32             #pod =cut
33              
34 1     1   4076 use Carp ();
  1         2  
  1         12  
35 1     1   7 use Scalar::Util ();
  1         2  
  1         241  
36              
37 1     1 0 13 sub type_uri { 'tag:codesimply.com,2008:rx/perl/code' }
38              
39             sub guts_from_arg {
40 5     5 0 1692 my ($class, $arg, $rx) = @_;
41 5   50     13 $arg ||= {};
42              
43 5         14 for my $key (keys %$arg) {
44 3 50       9 next if $key eq 'prototype';
45 0         0 Carp::croak(
46             "unknown argument $key in constructing " . $class->type_uri . " type",
47             );
48             }
49              
50             my $prototype_schema
51             = (! exists $arg->{prototype})
52             ? undef
53              
54             : (! defined $arg->{prototype})
55             ? $rx->make_schema('tag:codesimply.com,2008:rx/core/nil')
56              
57             : $rx->make_schema({
58             type => 'tag:codesimply.com,2008:rx/core/str',
59             value => $arg->{prototype}
60 5 100       25 });
    100          
61              
62 5         167 return { prototype_schema => $prototype_schema };
63             }
64              
65             sub assert_valid {
66 18     18 0 3539 my ($self, $value) = @_;
67              
68 18 100       42 unless (ref $value) {
69 5         25 $self->fail({
70             error => [ qw(type) ],
71             message => "found value is not a ref",
72             value => $value,
73             });
74             }
75              
76             # Should probably be checking _CALLABLE. -- rjbs, 2009-03-12
77 13 50       44 unless (Scalar::Util::reftype($value) eq 'CODE') {
78 0         0 $self->fail({
79             error => [ qw(type) ],
80             message => "found value is not a CODE ref",
81             value => $value,
82             });
83             }
84              
85 13 100 100     63 if (
86             defined $self->{prototype_schema}
87             && ! $self->{prototype_schema}->check(prototype $value)
88             ) {
89 6         382 $self->fail({
90             error => [ qw(prototype) ],
91             message => "subroutine prototype does not match requirement",
92             value => $value,
93             # data_path => [[ 'prototype', 'prototype', sub { "prototype($_[0])" } ]],
94             });
95             }
96              
97 7         62 return 1;
98             }
99              
100             1;
101              
102             __END__