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.19';
3 80     80   2808768 use v5.10;
  80         2255  
4 80     69   974 use strict;
  69         2558  
  69         2601  
5 69     65   637 use warnings;
  65         1451  
  65         2735  
6 65     50   482 use Carp qw(croak);
  50         100  
  50         2669  
7 50     50   23592 use Import::Into;
  50         111547  
  50         1580  
8              
9 50     50   18403 use Form::Tiny::Form;
  50         205  
  50         1963  
10 50     50   385 use Form::Tiny::Utils qw(:meta_handlers);
  50         107  
  50         18557  
11              
12             sub import
13             {
14 65     65   44387 my ($package, $caller) = (shift, scalar caller);
15              
16 65         525 my @wanted = (-base, @_);
17              
18             # very special case - do something UNLESS -nomoo was passed
19 65 100       418 unless ($package->_get_flag(\@wanted, -nomoo)) {
20 64         387 require Moo;
21 64         620 Moo->import::into($caller);
22             }
23              
24 65         34717 $package->ft_install($caller, @wanted);
25 65         46799 return;
26             }
27              
28             sub ft_install
29             {
30 65     65 0 276 my ($self, $caller, @import_flags) = @_;
31              
32 65         265 my $plugins_flag = $self->_get_flag(\@import_flags, 'plugins', 1);
33 65   100     302 my @plugins = ($self->_get_plugins(\@import_flags), @{$plugins_flag // []});
  65         415  
34              
35             # field context for form building
36 65         138 my $context;
37              
38 65         287 my $wanted = $self->ft_run_plugins($caller, \$context, @plugins);
39              
40             # create metapackage with roles
41 65         167 my $meta = create_form_meta($caller, @{$wanted->{meta_roles}});
  65         343  
42 65         1449 $meta->set_form_roles($wanted->{roles});
43              
44             # install DSL
45             {
46 50     50   447 no strict 'refs';
  50         135  
  50         2049  
  65         1625  
47 50     50   330 no warnings 'redefine';
  50         181  
  50         35495  
48              
49 358         1753 *{"${caller}::$_"} = $wanted->{subs}{$_}
50 65         167 foreach keys %{$wanted->{subs}};
  65         472  
51             }
52              
53 65         526 return \$context;
54             }
55              
56             sub ft_run_plugins
57             {
58 119     119 0 337 my ($self, $caller, $context_ref, @plugins) = @_;
59              
60 119         499 my $wanted = {
61             subs => {},
62             roles => [],
63             meta_roles => [],
64             };
65              
66 119         244 my %seen;
67 119         297 foreach my $plugin (@plugins) {
68 122         364 $plugin = "Form::Tiny::Plugin::$plugin";
69 122         371 $plugin =~ s/^.+\+//;
70 122 100       560 next if $seen{$plugin}++;
71              
72 48     48   23780 my $success = eval "use $plugin; 1";
  48         164  
  48         838  
  112         7872  
73              
74 112 50       521 croak "could not load plugin $plugin: $@"
75             unless $success;
76 112 50       760 croak "$plugin is not a Form::Tiny::Plugin"
77             unless $plugin->isa('Form::Tiny::Plugin');
78              
79 112         494 $self->_merge_behaviors($wanted, $plugin->plugin($caller, $context_ref));
80             }
81              
82 119         428 return $wanted;
83             }
84              
85             sub _get_plugins
86             {
87 65     65   201 my ($self, $flags) = @_;
88              
89 65         451 my %known_flags = (
90             -base => ['Base'],
91             -strict => ['Strict'],
92             -filtered => ['Filtered'],
93              
94             # legacy no-op flags
95             -consistent => [],
96             );
97              
98 65         133 my @plugins;
99 65         193 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         177 push @plugins, @{$known_flags{$flag}};
  107         314  
104             }
105              
106 65         289 return @plugins;
107             }
108              
109             sub _merge_behaviors
110             {
111 112     112   410 my ($self, $wanted, $behaviors) = @_;
112              
113 112   100     197 %{$wanted->{subs}} = (%{$wanted->{subs}}, %{$behaviors->{subs} // {}});
  112         502  
  112         387  
  112         616  
114 112   100     285 push @{$wanted->{roles}}, @{$behaviors->{roles} // []};
  112         236  
  112         544  
115 112   100     259 push @{$wanted->{meta_roles}}, @{$behaviors->{meta_roles} // []};
  112         226  
  112         892  
116             }
117              
118             sub _get_flag
119             {
120 130     130   375 my ($self, $flags, $wanted, $with_param) = @_;
121 130   100     698 $with_param //= 0;
122              
123 130         479 for my $n (0 .. $#$flags) {
124 228 100       909 if ($flags->[$n] eq $wanted) {
125 6         11 my $param = 1;
126 6 100       29 if ($with_param) {
127 5 50       18 croak "Form::Tiny flag $wanted needs a parameter"
128             if $n == $#$flags;
129 5         15 $param = $flags->[$n + 1];
130             }
131              
132 6         16 splice @$flags, $n, 1 + $with_param;
133 6         21 return $param;
134             }
135             }
136              
137 124         412 return;
138             }
139              
140             1;
141              
142             __END__