File Coverage

blib/lib/Specio/Constraint/Role/DoesType.pm
Criterion Covered Total %
statement 47 47 100.0
branch 13 14 92.8
condition 5 6 83.3
subroutine 11 11 100.0
pod n/a
total 76 78 97.4


line stmt bran cond sub pod time code
1             package Specio::Constraint::Role::DoesType;
2              
3 3     3   29 use strict;
  3         7  
  3         92  
4 3     3   14 use warnings;
  3         10  
  3         143  
5              
6             our $VERSION = '0.46';
7              
8 3     3   20 use Role::Tiny;
  3         8  
  3         40  
9 3     3   530 use Scalar::Util qw( blessed );
  3         6  
  3         156  
10 3     3   20 use Specio::PartialDump qw( partial_dump );
  3         6  
  3         144  
11 3     3   21 use Storable qw( dclone );
  3         6  
  3         162  
12              
13 3     3   22 use Specio::Constraint::Role::Interface;
  3         7  
  3         1700  
14             with 'Specio::Constraint::Role::Interface';
15              
16             {
17             ## no critic (Subroutines::ProtectPrivateSubs)
18             my $attrs = dclone( Specio::Constraint::Role::Interface::_attrs() );
19             ## use critic
20              
21             for my $name (qw( parent _inline_generator )) {
22             $attrs->{$name}{init_arg} = undef;
23             $attrs->{$name}{builder}
24             = $name =~ /^_/ ? '_build' . $name : '_build_' . $name;
25             }
26              
27             $attrs->{role} = {
28             isa => 'Str',
29             required => 1,
30             };
31              
32             ## no critic (Subroutines::ProhibitUnusedPrivateSubroutines)
33             sub _attrs {
34 12     12   28 return $attrs;
35             }
36             }
37              
38             ## no critic (Subroutines::ProhibitUnusedPrivateSubroutines)
39             sub _wrap_message_generator {
40 9     9   16 my $self = shift;
41 9         25 my $generator = shift;
42              
43 9         56 my $type = ( split /::/, blessed $self)[-1];
44 9         33 my $role = $self->role;
45 9         45 my $allow_classes = $self->_allow_classes;
46              
47 9 50       30 unless ( defined $generator ) {
48             $generator = sub {
49 102     102   164 shift;
50 102         199 my $value = shift;
51              
52 102 100       315 return "An undef will never pass an $type check (wants $role)"
53             unless defined $value;
54              
55 98 100 100     490 if ( ref $value && !blessed $value ) {
56 16         68 my $dump = partial_dump($value);
57             return
58 16         121 "An unblessed reference ($dump) will never pass an $type check (wants $role)";
59             }
60              
61 82 100       241 if ( !blessed $value) {
62             return
63 34 100       142 "An empty string will never pass an $type check (wants $role)"
64             unless length $value;
65              
66 30 100       156 if (
67             $value =~ /\A
68             \s*
69             -?[0-9]+(?:\.[0-9]+)?
70             (?:[Ee][\-+]?[0-9]+)?
71             \s*
72             \z/xs
73             ) {
74             return
75 17         142 "A number ($value) will never pass an $type check (wants $role)";
76             }
77              
78 13 100       42 if ( !$allow_classes ) {
79 7         27 my $dump = partial_dump($value);
80             return
81 7         55 "A plain scalar ($dump) will never pass an $type check (wants $role)";
82             }
83             }
84              
85 54         140 my $got = blessed $value;
86 54   66     202 $got ||= $value;
87              
88 54         333 return "The $got class does not consume the $role role";
89 9         64 };
90             }
91              
92 9     102   46 return sub { $generator->( undef, @_ ) };
  102         4010  
93             }
94             ## use critic
95              
96             1;
97              
98             # ABSTRACT: Provides a common implementation for Specio::Constraint::AnyDoes and Specio::Constraint::ObjectDoes
99              
100             __END__
101              
102             =pod
103              
104             =encoding UTF-8
105              
106             =head1 NAME
107              
108             Specio::Constraint::Role::DoesType - Provides a common implementation for Specio::Constraint::AnyDoes and Specio::Constraint::ObjectDoes
109              
110             =head1 VERSION
111              
112             version 0.46
113              
114             =head1 DESCRIPTION
115              
116             See L<Specio::Constraint::AnyDoes> and L<Specio::Constraint::ObjectDoes> for
117             details.
118              
119             =head1 SUPPORT
120              
121             Bugs may be submitted at L<https://github.com/houseabsolute/Specio/issues>.
122              
123             I am also usually active on IRC as 'autarch' on C<irc://irc.perl.org>.
124              
125             =head1 SOURCE
126              
127             The source code repository for Specio can be found at L<https://github.com/houseabsolute/Specio>.
128              
129             =head1 AUTHOR
130              
131             Dave Rolsky <autarch@urth.org>
132              
133             =head1 COPYRIGHT AND LICENSE
134              
135             This software is Copyright (c) 2012 - 2020 by Dave Rolsky.
136              
137             This is free software, licensed under:
138              
139             The Artistic License 2.0 (GPL Compatible)
140              
141             The full text of the license can be found in the
142             F<LICENSE> file included with this distribution.
143              
144             =cut