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   3250929 use strict;
  16         133  
  16         471  
3 16     16   88 use warnings;
  16         32  
  16         660  
4             our $VERSION = "0.12";
5 16     16   82 use Carp ();
  16         28  
  16         291  
6 16     16   3833 use PadWalker qw/var_name/;
  16         7660  
  16         1049  
7              
8 16     16   108 use Exporter 'import';
  16         34  
  16         829  
9             our @EXPORT = qw/args args_pos/;
10              
11             $Carp::CarpInternal{+__PACKAGE__}++;
12              
13 16     16   4166 use Smart::Args::TypeTiny::Check qw/check_rule/;
  16         52  
  16         10228  
14              
15             my %is_invocant = map { ($_ => 1) } qw($self $class);
16              
17             sub args {
18             {
19 48     48 1 88438 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         361 () = CORE::caller(1);
23             }
24              
25 48 50       174 if (@_) {
26 48   50     373 my $name = var_name(1, \$_[0]) || '';
27 48 100       160 if ($is_invocant{$name}) { # seems instance/class method call
28 10         43 $name =~ s/^\$//;
29 10         21 $_[0] = shift @DB::args;
30 10 100       23 if (defined $_[1]) { # has rule?
31 3         14 $_[0] = check_rule($_[1], $_[0], 1, $name);
32 2         5 shift;
33             }
34 9         15 shift;
35             }
36             }
37              
38             my $args = (@DB::args == 1 && ref $DB::args[0] eq 'HASH')
39 47 100 66     253 ? +{ %{$DB::args[0]} } # must be hash
  1         6  
40             : +{ @DB::args }; # must be key-value list
41 47         86 my $kv = {};
42              
43             # args my $var => RULE
44             # ~~~~ ~~~~
45             # undef defined
46              
47 47         136 for (my $i = 0; $i < @_; $i++) {
48 62 50       236 (my $name = var_name(1, \$_[$i]))
49             or Carp::croak('Usage: args my $var => RULE, ...');
50 62         275 $name =~ s/^\$//;
51              
52             # with rule (my $foo => RULE, ...)
53 62 100       212 if (defined $_[$i+1]) {
54 55         247 $_[$i] = $kv->{$name} = check_rule($_[$i+1], $args->{$name}, exists $args->{$name}, $name);
55 41         112 delete $args->{$name};
56 41         120 $i++;
57             }
58             # without rule (my $foo, my $bar, ...)
59             else {
60 7 100       20 unless (exists $args->{$name}) {
61 1         55 Carp::confess("Required parameter '$name' not passed");
62             }
63 6         23 $_[$i] = $kv->{$name} = delete $args->{$name};
64             }
65             }
66              
67 32         120 for my $name (sort keys %$args) {
68 3         396 Carp::confess("Unexpected parameter '$name' passed");
69             }
70              
71 29         102 return $kv;
72             }
73              
74             sub args_pos {
75             {
76 28     28 1 11281 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         181 () = CORE::caller(1);
80             }
81              
82 28 50       96 if (@_) {
83 28   50     126 my $name = var_name(1, \$_[0]) || '';
84 28 100       85 if ($is_invocant{$name}) { # seems instance/class method call
85 7         28 $name =~ s/^\$//;
86 7         14 $_[0] = shift @DB::args;
87 7 100       14 if (defined $_[1]) { # has rule?
88 2         6 $_[0] = check_rule($_[1], $_[0], 1, $name);
89 1         2 shift;
90             }
91 6         8 shift;
92             }
93             }
94              
95 27         65 my $args = [@DB::args];
96 27         45 my $kv = {};
97              
98             # args my $var => RULE
99             # ~~~~ ~~~~
100             # undef defined
101              
102 27         82 for (my $i = 0; $i < @_; $i++) {
103 38 50       146 (my $name = var_name(1, \$_[$i]))
104             or Carp::croak('Usage: args_pos my $var => RULE, ...');
105 38         147 $name =~ s/^\$//;
106              
107             # with rule (my $foo => RULE, ...)
108 38 100       114 if (defined $_[$i+1]) {
109 33         122 $_[$i] = $kv->{$name} = check_rule($_[$i+1], $args->[0], @$args > 0, $name);
110 25         51 shift @$args;
111 25         67 $i++;
112             }
113             # without rule (my $foo, my $bar, ...)
114             else {
115 5 50       17 unless (@$args > 0) {
116 0         0 Carp::confess("Required parameter '$name' not passed");
117             }
118 5         35 $_[$i] = $kv->{$name} = shift @$args;
119             }
120             }
121              
122 19 100       49 if (@$args) {
123 2         147 Carp::confess('Too many parameters passed');
124             }
125              
126 17         46 return $kv;
127             }
128              
129             1;
130             __END__