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 21 95.2
pod 0 1 0.0
total 106 117 90.6


line stmt bran cond sub pod time code
1 2     2   453218 use 5.014;
  2         16  
2 2     2   9 use strict;
  2         6  
  2         40  
3 2     2   10 use warnings;
  2         3  
  2         129  
4              
5             package results::exceptions;
6              
7             our $AUTHORITY = 'cpan:TOBYINK';
8             our $VERSION = '0.004';
9              
10 2     2   817 use results ();
  2         5  
  2         52  
11 2     2   24 use B ();
  2         4  
  2         36  
12 2     2   9 use Exporter::Shiny;
  2         5  
  2         11  
13              
14             sub _exporter_fail {
15 6     6   122164 my ( $class, $err_kind, $opts, $globals ) = @_;
16 6         13 my $caller = $globals->{into};
17              
18 6 100       300 $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         22 my $exception_class = "$caller\::Exception::$err_kind";
29 5         20 $class->create_exception_class( $exception_class, $err_kind, $opts );
30              
31 5         399 $err_kind => eval sprintf( 'sub () { %s }', B::perlstring($exception_class) );
32             }
33              
34             sub create_exception_class {
35 7     7 0 9789 my ( $class, $exception_class, $err_kind, $opts ) = @_;
36 7   100     28 $opts //= {};
37              
38 2     2   444 no strict 'refs';
  2         4  
  2         911  
39 7         60 *{"$exception_class\::new"} = sub {
40 9     9   36448 my $class = shift;
41 9 50       66 bless { @_==1 ? %{$_[0]} : @_ }, $class;
  0         0  
42 7         24 };
43 7         27 *{"$exception_class\::err"} = sub {
44 6     6   17 my $class = shift;
45 6         58 results::err( $class->new( @_ ) );
46 7         27 };
47 7         25 *{"$exception_class\::throw"} = sub {
48 0     0   0 my $class = shift;
49 0         0 die( $class->new( @_ ) );
50 7         25 };
51 7         25 *{"$exception_class\::err_kind"} = sub {
52 3     3   12 $err_kind
53 7         19 };
54 7         24 *{"$exception_class\::DOES"} = sub {
55 5     5   1655 my ( $class, $role ) = @_;
56 5 50       33 return 1 if $role eq __PACKAGE__;
57 0         0 $class->SUPER::DOES( $role );
58 7         24 };
59 7         28 *{"$exception_class\::to_string"} = sub {
60 5     5   11 my $self = shift;
61 5 100       25 if ( 'CODE' eq ref $opts->{to_string} ) {
    100          
62 2         10 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         35 };
71 7   100     16 for my $attr ( @{ $opts->{has} // [] } ) {
  7         56  
72 3     6   9 *{"$exception_class\::$attr"} = sub { $_[0]{$attr} };
  3         15  
  6         104  
73             }
74            
75 7         14 local $@;
76 2 50   2   18 eval qq/
  2     2   4  
  2     2   18  
  0     1   0  
  2     3   16  
  2         4  
  2         22  
  3         534  
  2         17  
  2         4  
  2         14  
  3         528  
  1         7  
  1         2  
  1         13  
  0         0  
  7         734  
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__