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   5509025 use strict;
  16         51  
  16         645  
3 16     16   86 use warnings;
  16         68  
  16         1312  
4             our $VERSION = "0.14";
5 16     16   127 use Carp ();
  16         29  
  16         439  
6 16     16   8390 use PadWalker qw/var_name/;
  16         13716  
  16         3013  
7              
8 16     16   117 use Exporter 'import';
  16         29  
  16         1156  
9             our @EXPORT = qw/args args_pos/;
10              
11             $Carp::CarpInternal{+__PACKAGE__}++;
12              
13 16     16   8437 use Smart::Args::TypeTiny::Check qw/check_rule/;
  16         99  
  16         17869  
14              
15             my %is_invocant = map { ($_ => 1) } qw($self $class);
16              
17             sub args {
18             {
19 57     57 1 4679355 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 57         516 () = CORE::caller(1);
23             }
24              
25 57 50       1620 if (@_) {
26 57   50     494 my $name = var_name(1, \$_[0]) || '';
27 57 100       299 if ($is_invocant{$name}) { # seems instance/class method call
28 10         52 $name =~ s/^\$//;
29 10         28 $_[0] = shift @DB::args;
30 10 100       34 if (defined $_[1]) { # has rule?
31 3         18 $_[0] = check_rule($_[1], $_[0], 1, $name);
32 2         16 shift;
33             }
34 9         19 shift;
35             }
36             }
37              
38             my $args = (@DB::args == 1 && ref $DB::args[0] eq 'HASH')
39 56 100 66     413 ? +{ %{$DB::args[0]} } # must be hash
  1         5  
40             : +{ @DB::args }; # must be key-value list
41 56         117 my $kv = {};
42              
43             # args my $var => RULE
44             # ~~~~ ~~~~
45             # undef defined
46              
47 56         216 for (my $i = 0; $i < @_; $i++) {
48 71 50       382 (my $name = var_name(1, \$_[$i]))
49             or Carp::croak('Usage: args my $var => RULE, ...');
50 71         335 $name =~ s/^\$//;
51              
52             # with rule (my $foo => RULE, ...)
53 71 100       233 if (defined $_[$i+1]) {
54 64         461 $_[$i] = $kv->{$name} = check_rule($_[$i+1], $args->{$name}, exists $args->{$name}, $name);
55 49         133 delete $args->{$name};
56 49         184 $i++;
57             }
58             # without rule (my $foo, my $bar, ...)
59             else {
60 7 100       30 unless (exists $args->{$name}) {
61 1         99 Carp::confess("Required parameter '$name' not passed");
62             }
63 6         33 $_[$i] = $kv->{$name} = delete $args->{$name};
64             }
65             }
66              
67 40         155 for my $name (sort keys %$args) {
68 3         456 Carp::confess("Unexpected parameter '$name' passed");
69             }
70              
71 37         250 return $kv;
72             }
73              
74             sub args_pos {
75             {
76 28     28 1 18539 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         271 () = CORE::caller(1);
80             }
81              
82 28 50       133 if (@_) {
83 28   50     180 my $name = var_name(1, \$_[0]) || '';
84 28 100       128 if ($is_invocant{$name}) { # seems instance/class method call
85 7         31 $name =~ s/^\$//;
86 7         19 $_[0] = shift @DB::args;
87 7 100       18 if (defined $_[1]) { # has rule?
88 2         12 $_[0] = check_rule($_[1], $_[0], 1, $name);
89 1         4 shift;
90             }
91 6         12 shift;
92             }
93             }
94              
95 27         64 my $args = [@DB::args];
96 27         59 my $kv = {};
97              
98             # args my $var => RULE
99             # ~~~~ ~~~~
100             # undef defined
101              
102 27         88 for (my $i = 0; $i < @_; $i++) {
103 38 50       169 (my $name = var_name(1, \$_[$i]))
104             or Carp::croak('Usage: args_pos my $var => RULE, ...');
105 38         144 $name =~ s/^\$//;
106              
107             # with rule (my $foo => RULE, ...)
108 38 100       129 if (defined $_[$i+1]) {
109 33         179 $_[$i] = $kv->{$name} = check_rule($_[$i+1], $args->[0], @$args > 0, $name);
110 25         76 shift @$args;
111 25         100 $i++;
112             }
113             # without rule (my $foo, my $bar, ...)
114             else {
115 5 50       22 unless (@$args > 0) {
116 0         0 Carp::confess("Required parameter '$name' not passed");
117             }
118 5         27 $_[$i] = $kv->{$name} = shift @$args;
119             }
120             }
121              
122 19 100       102 if (@$args) {
123 2         234 Carp::confess('Too many parameters passed');
124             }
125              
126 17         64 return $kv;
127             }
128              
129             1;
130             __END__