File Coverage

blib/lib/Form/Tiny.pm
Criterion Covered Total %
statement 92 92 100.0
branch 12 16 75.0
condition 10 10 100.0
subroutine 16 16 100.0
pod 0 2 0.0
total 130 136 95.5


line stmt bran cond sub pod time code
1             package Form::Tiny;
2             $Form::Tiny::VERSION = '2.20';
3 80     80   2846481 use v5.10;
  80         2161  
4 80     69   1072 use strict;
  69         2294  
  69         2720  
5 69     65   643 use warnings;
  65         1454  
  65         2747  
6 65     50   589 use Carp qw(croak);
  50         87  
  50         2766  
7 50     50   24947 use Import::Into;
  50         113103  
  50         1572  
8              
9 50     50   18439 use Form::Tiny::Form;
  50         178  
  50         1901  
10 50     50   371 use Form::Tiny::Utils qw(:meta_handlers);
  50         125  
  50         18259  
11              
12             sub import
13             {
14 65     65   43755 my ($package, $caller) = (shift, scalar caller);
15              
16 65         497 my @wanted = (-base, @_);
17              
18             # very special case - do something UNLESS -nomoo was passed
19 65 100       392 unless ($package->_get_flag(\@wanted, -nomoo)) {
20 64         374 require Moo;
21 64         564 Moo->import::into($caller);
22             }
23              
24 65         34078 $package->ft_install($caller, @wanted);
25 65         45242 return;
26             }
27              
28             sub ft_install
29             {
30 65     65 0 295 my ($self, $caller, @import_flags) = @_;
31              
32 65         243 my $plugins_flag = $self->_get_flag(\@import_flags, 'plugins', 1);
33 65   100     304 my @plugins = ($self->_get_plugins(\@import_flags), @{$plugins_flag // []});
  65         436  
34              
35             # field context for form building
36 65         141 my $context;
37              
38 65         269 my $wanted = $self->ft_run_plugins($caller, \$context, @plugins);
39              
40             # create metapackage with roles
41 65         145 my $meta = create_form_meta($caller, @{$wanted->{meta_roles}});
  65         361  
42 65         1403 $meta->set_form_roles($wanted->{roles});
43              
44             # install DSL
45             {
46 50     50   403 no strict 'refs';
  50         128  
  50         2144  
  65         1563  
47 50     50   334 no warnings 'redefine';
  50         145  
  50         35996  
48              
49 358         1687 *{"${caller}::$_"} = $wanted->{subs}{$_}
50 65         193 foreach keys %{$wanted->{subs}};
  65         476  
51             }
52              
53 65         504 return \$context;
54             }
55              
56             sub ft_run_plugins
57             {
58 119     119 0 363 my ($self, $caller, $context_ref, @plugins) = @_;
59              
60 119         511 my $wanted = {
61             subs => {},
62             roles => [],
63             meta_roles => [],
64             };
65              
66 119         223 my %seen;
67 119         292 foreach my $plugin (@plugins) {
68 122         374 $plugin = "Form::Tiny::Plugin::$plugin";
69 122         369 $plugin =~ s/^.+\+//;
70 122 100       605 next if $seen{$plugin}++;
71              
72 48     48   23483 my $success = eval "use $plugin; 1";
  48         184  
  48         805  
  112         7804  
73              
74 112 50       511 croak "could not load plugin $plugin: $@"
75             unless $success;
76 112 50       740 croak "$plugin is not a Form::Tiny::Plugin"
77             unless $plugin->isa('Form::Tiny::Plugin');
78              
79 112         476 $self->_merge_behaviors($wanted, $plugin->plugin($caller, $context_ref));
80             }
81              
82 119         389 return $wanted;
83             }
84              
85             sub _get_plugins
86             {
87 65     65   199 my ($self, $flags) = @_;
88              
89 65         426 my %known_flags = (
90             -base => ['Base'],
91             -strict => ['Strict'],
92             -filtered => ['Filtered'],
93              
94             # legacy no-op flags
95             -consistent => [],
96             );
97              
98 65         137 my @plugins;
99 65         185 foreach my $flag (@$flags) {
100             croak "no Form::Tiny import behavior for: $flag"
101 107 50       330 unless exists $known_flags{$flag};
102              
103 107         171 push @plugins, @{$known_flags{$flag}};
  107         320  
104             }
105              
106 65         301 return @plugins;
107             }
108              
109             sub _merge_behaviors
110             {
111 112     112   365 my ($self, $wanted, $behaviors) = @_;
112              
113 112   100     209 %{$wanted->{subs}} = (%{$wanted->{subs}}, %{$behaviors->{subs} // {}});
  112         481  
  112         386  
  112         594  
114 112   100     277 push @{$wanted->{roles}}, @{$behaviors->{roles} // []};
  112         230  
  112         536  
115 112   100     203 push @{$wanted->{meta_roles}}, @{$behaviors->{meta_roles} // []};
  112         228  
  112         810  
116             }
117              
118             sub _get_flag
119             {
120 130     130   398 my ($self, $flags, $wanted, $with_param) = @_;
121 130   100     669 $with_param //= 0;
122              
123 130         467 for my $n (0 .. $#$flags) {
124 228 100       795 if ($flags->[$n] eq $wanted) {
125 6         15 my $param = 1;
126 6 100       19 if ($with_param) {
127 5 50       16 croak "Form::Tiny flag $wanted needs a parameter"
128             if $n == $#$flags;
129 5         13 $param = $flags->[$n + 1];
130             }
131              
132 6         17 splice @$flags, $n, 1 + $with_param;
133 6         20 return $param;
134             }
135             }
136              
137 124         393 return;
138             }
139              
140             1;
141              
142             __END__