File Coverage

blib/lib/results/exceptions.pm
Criterion Covered Total %
statement 73 79 92.4
branch 9 12 75.0
condition 4 4 100.0
subroutine 20 22 90.9
pod 0 1 0.0
total 106 118 89.8


line stmt bran cond sub pod time code
1 2     2   456385 use 5.014;
  2         19  
2 2     2   11 use strict;
  2         4  
  2         38  
3 2     2   10 use warnings;
  2         7  
  2         121  
4              
5             package results::exceptions;
6              
7             our $AUTHORITY = 'cpan:TOBYINK';
8             our $VERSION = '0.006';
9              
10 2     2   862 use results ();
  2         6  
  2         43  
11 2     2   13 use B ();
  2         7  
  2         48  
12 2     2   10 use Exporter::Shiny;
  2         3  
  2         30  
13              
14             sub _exporter_fail {
15 6     6   89446 my ( $class, $err_kind, $opts, $globals ) = @_;
16 6         12 my $caller = $globals->{into};
17              
18 6 100       272 $err_kind =~ /
19             \A
20             (?:[[:upper:]][[:lower:]]*)
21             (?:
22             (?:[[:upper:]][[:lower:]]*)
23             | [0-9]+
24             )*
25             \z
26             /x or Carp::croak( "Bad err_kind name: $err_kind" );
27              
28 5         38 my $exception_class = "$caller\::Exception::$err_kind";
29 5         20 $class->create_exception_class( $exception_class, $err_kind, $opts );
30              
31 5         391 $err_kind => eval sprintf( 'sub () { %s }', B::perlstring($exception_class) );
32             }
33              
34             sub create_exception_class {
35 7     7 0 9943 my ( $class, $exception_class, $err_kind, $opts ) = @_;
36 7   100     29 $opts //= {};
37              
38 2     2   453 no strict 'refs';
  2         12  
  2         935  
39 7         70 *{"$exception_class\::new"} = sub {
40 9     9   7423 my $class = shift;
41 9 50       57 bless { @_==1 ? %{$_[0]} : @_ }, $class;
  0         0  
42 7         27 };
43 7         26 *{"$exception_class\::err"} = sub {
44 6     6   14 my $class = shift;
45 6         20 results::err( $class->new( @_ ) );
46 7         26 };
47 7         36 *{"$exception_class\::throw"} = sub {
48 0     0   0 my $class = shift;
49 0         0 die( $class->new( @_ ) );
50 7         35 };
51 7         24 *{"$exception_class\::err_kind"} = sub {
52 3     3   13 $err_kind
53 7         19 };
54 7         23 *{"$exception_class\::DOES"} = sub {
55 5     5   1526 my ( $class, $role ) = @_;
56 5 50       37 return 1 if $role eq __PACKAGE__;
57 0         0 $class->SUPER::DOES( $role );
58 7         24 };
59 7         32 *{"$exception_class\::to_string"} = sub {
60 5     5   15 my $self = shift;
61 5 100       26 if ( 'CODE' eq ref $opts->{to_string} ) {
    100          
62 2         11 return $opts->{to_string}->( $self );
63             }
64             elsif ( defined $opts->{to_string} ) {
65 1         7 return $opts->{to_string};
66             }
67             else {
68 2         14 return $err_kind;
69             }
70 7         40 };
71 7   100     11 for my $attr ( @{ $opts->{has} // [] } ) {
  7         45  
72 3     6   11 *{"$exception_class\::$attr"} = sub { $_[0]{$attr} };
  3     6   45  
  6         124  
73             }
74            
75 7         14 local $@;
76 2 50   2   18 eval qq/
  2     2   4  
  2     2   26  
  0     1   0  
  2     0   14  
  2         8  
  2         15  
  3         558  
  2         14  
  2         5  
  2         15  
  3         543  
  1         7  
  1         3  
  1         7  
  0         0  
  7         770  
77             package $exception_class;
78             use overload (
79             fallback => !!1,
80             q[""] => q[to_string],
81             bool => sub { !!1 },
82             );
83             1;
84             / or die( $@ );
85             }
86              
87             1;
88              
89             __END__