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   4582154 use strict;
  16         160  
  16         518  
3 16     16   88 use warnings;
  16         28  
  16         752  
4             our $VERSION = "0.11";
5 16     16   92 use Carp ();
  16         36  
  16         303  
6 16     16   4528 use PadWalker qw/var_name/;
  16         9130  
  16         1184  
7              
8 16     16   113 use Exporter 'import';
  16         32  
  16         901  
9             our @EXPORT = qw/args args_pos/;
10              
11             $Carp::CarpInternal{+__PACKAGE__}++;
12              
13 16     16   4937 use Smart::Args::TypeTiny::Check qw/check_rule/;
  16         60  
  16         11265  
14              
15             my %is_invocant = map { ($_ => 1) } qw($self $class);
16              
17             sub args {
18             {
19 48     48 1 105205 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         459 () = CORE::caller(1);
23             }
24              
25 48 50       220 if (@_) {
26 48   50     460 my $name = var_name(1, \$_[0]) || '';
27 48 100       207 if ($is_invocant{$name}) { # seems instance/class method call
28 10         58 $name =~ s/^\$//;
29 10         29 $_[0] = shift @DB::args;
30 10 100       32 if (defined $_[1]) { # has rule?
31 3         19 $_[0] = check_rule($_[1], $_[0], 1, $name);
32 2         89 shift;
33             }
34 9         22 shift;
35             }
36             }
37              
38             my $args = (@DB::args == 1 && ref $DB::args[0] eq 'HASH')
39 47 100 66     307 ? +{ %{$DB::args[0]} } # must be hash
  1         4  
40             : +{ @DB::args }; # must be key-value list
41 47         121 my $kv = {};
42              
43             # args my $var => RULE
44             # ~~~~ ~~~~
45             # undef defined
46              
47 47         182 for (my $i = 0; $i < @_; $i++) {
48 62 50       311 (my $name = var_name(1, \$_[$i]))
49             or Carp::croak('Usage: args my $var => RULE, ...');
50 62         333 $name =~ s/^\$//;
51              
52             # with rule (my $foo => RULE, ...)
53 62 100       223 if (defined $_[$i+1]) {
54 55         338 $_[$i] = $kv->{$name} = check_rule($_[$i+1], $args->{$name}, exists $args->{$name}, $name);
55 41         2726 delete $args->{$name};
56 41         170 $i++;
57             }
58             # without rule (my $foo, my $bar, ...)
59             else {
60 7 100       23 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         155 for my $name (sort keys %$args) {
68 3         357 Carp::confess("Unexpected parameter '$name' passed");
69             }
70              
71 29         133 return $kv;
72             }
73              
74             sub args_pos {
75             {
76 28     28 1 13282 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         214 () = CORE::caller(1);
80             }
81              
82 28 50       167 if (@_) {
83 28   50     150 my $name = var_name(1, \$_[0]) || '';
84 28 100       156 if ($is_invocant{$name}) { # seems instance/class method call
85 7         38 $name =~ s/^\$//;
86 7         21 $_[0] = shift @DB::args;
87 7 100       28 if (defined $_[1]) { # has rule?
88 2         11 $_[0] = check_rule($_[1], $_[0], 1, $name);
89 1         17 shift;
90             }
91 6         13 shift;
92             }
93             }
94              
95 27         72 my $args = [@DB::args];
96 27         53 my $kv = {};
97              
98             # args my $var => RULE
99             # ~~~~ ~~~~
100             # undef defined
101              
102 27         103 for (my $i = 0; $i < @_; $i++) {
103 38 50       153 (my $name = var_name(1, \$_[$i]))
104             or Carp::croak('Usage: args_pos my $var => RULE, ...');
105 38         165 $name =~ s/^\$//;
106              
107             # with rule (my $foo => RULE, ...)
108 38 100       121 if (defined $_[$i+1]) {
109 33         136 $_[$i] = $kv->{$name} = check_rule($_[$i+1], $args->[0], @$args > 0, $name);
110 25         349 shift @$args;
111 25         77 $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         27 $_[$i] = $kv->{$name} = shift @$args;
119             }
120             }
121              
122 19 100       59 if (@$args) {
123 2         153 Carp::confess('Too many parameters passed');
124             }
125              
126 17         55 return $kv;
127             }
128              
129             1;
130             __END__