File Coverage

blib/lib/Smart/Args/TypeTiny.pm
Criterion Covered Total %
statement 70 71 98.5
branch 23 28 82.1
condition 4 7 57.1
subroutine 8 8 100.0
pod 2 2 100.0
total 107 116 92.2


line stmt bran cond sub pod time code
1             package Smart::Args::TypeTiny;
2 16     16   3912473 use strict;
  16         128  
  16         410  
3 16     16   70 use warnings;
  16         29  
  16         521  
4             our $VERSION = "0.13";
5 16     16   69 use Carp ();
  16         26  
  16         262  
6 16     16   5789 use PadWalker qw/var_name/;
  16         8844  
  16         854  
7              
8 16     16   91 use Exporter 'import';
  16         30  
  16         822  
9             our @EXPORT = qw/args args_pos/;
10              
11             $Carp::CarpInternal{+__PACKAGE__}++;
12              
13 16     16   5484 use Smart::Args::TypeTiny::Check qw/check_rule/;
  16         39  
  16         10912  
14              
15             my %is_invocant = map { ($_ => 1) } qw($self $class);
16              
17             sub args {
18             {
19 48     48 1 109645 package DB;
20             # call of caller in DB package sets @DB::args,
21             # which requires list context, but we don't need return values
22 48         347 () = CORE::caller(1);
23             }
24              
25 48 50       168 if (@_) {
26 48   50     372 my $name = var_name(1, \$_[0]) || '';
27 48 100       150 if ($is_invocant{$name}) { # seems instance/class method call
28 10         42 $name =~ s/^\$//;
29 10         21 $_[0] = shift @DB::args;
30 10 100       24 if (defined $_[1]) { # has rule?
31 3         13 $_[0] = check_rule($_[1], $_[0], 1, $name);
32 2         4 shift;
33             }
34 9         14 shift;
35             }
36             }
37              
38             my $args = (@DB::args == 1 && ref $DB::args[0] eq 'HASH')
39 47 100 66     230 ? +{ %{$DB::args[0]} } # must be hash
  1         4  
40             : +{ @DB::args }; # must be key-value list
41 47         85 my $kv = {};
42              
43             # args my $var => RULE
44             # ~~~~ ~~~~
45             # undef defined
46              
47 47         163 for (my $i = 0; $i < @_; $i++) {
48 62 50       231 (my $name = var_name(1, \$_[$i]))
49             or Carp::croak('Usage: args my $var => RULE, ...');
50 62         262 $name =~ s/^\$//;
51              
52             # with rule (my $foo => RULE, ...)
53 62 100       169 if (defined $_[$i+1]) {
54 55         232 $_[$i] = $kv->{$name} = check_rule($_[$i+1], $args->{$name}, exists $args->{$name}, $name);
55 41         100 delete $args->{$name};
56 41         116 $i++;
57             }
58             # without rule (my $foo, my $bar, ...)
59             else {
60 7 100       43 unless (exists $args->{$name}) {
61 1         56 Carp::confess("Required parameter '$name' not passed");
62             }
63 6         27 $_[$i] = $kv->{$name} = delete $args->{$name};
64             }
65             }
66              
67 32         115 for my $name (sort keys %$args) {
68 3         303 Carp::confess("Unexpected parameter '$name' passed");
69             }
70              
71 29         126 return $kv;
72             }
73              
74             sub args_pos {
75             {
76 28     28 1 12730 package DB;
77             # call of caller in DB package sets @DB::args,
78             # which requires list context, but we don't need return values
79 28         177 () = CORE::caller(1);
80             }
81              
82 28 50       90 if (@_) {
83 28   50     121 my $name = var_name(1, \$_[0]) || '';
84 28 100       80 if ($is_invocant{$name}) { # seems instance/class method call
85 7         29 $name =~ s/^\$//;
86 7         14 $_[0] = shift @DB::args;
87 7 100       14 if (defined $_[1]) { # has rule?
88 2         8 $_[0] = check_rule($_[1], $_[0], 1, $name);
89 1         3 shift;
90             }
91 6         8 shift;
92             }
93             }
94              
95 27         65 my $args = [@DB::args];
96 27         50 my $kv = {};
97              
98             # args my $var => RULE
99             # ~~~~ ~~~~
100             # undef defined
101              
102 27         89 for (my $i = 0; $i < @_; $i++) {
103 38 50       126 (my $name = var_name(1, \$_[$i]))
104             or Carp::croak('Usage: args_pos my $var => RULE, ...');
105 38         141 $name =~ s/^\$//;
106              
107             # with rule (my $foo => RULE, ...)
108 38 100       108 if (defined $_[$i+1]) {
109 33         120 $_[$i] = $kv->{$name} = check_rule($_[$i+1], $args->[0], @$args > 0, $name);
110 25         51 shift @$args;
111 25         71 $i++;
112             }
113             # without rule (my $foo, my $bar, ...)
114             else {
115 5 50       16 unless (@$args > 0) {
116 0         0 Carp::confess("Required parameter '$name' not passed");
117             }
118 5         21 $_[$i] = $kv->{$name} = shift @$args;
119             }
120             }
121              
122 19 100       48 if (@$args) {
123 2         115 Carp::confess('Too many parameters passed');
124             }
125              
126 17         47 return $kv;
127             }
128              
129             1;
130             __END__