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.26';
3 85     85   4699640 use v5.10;
  85         2227  
4 85     73   1122 use strict;
  73         3115  
  73         3908  
5 73     68   771 use warnings;
  68         1797  
  68         5119  
6 68     52   651 use Carp qw(croak);
  52         149  
  52         3399  
7 52     52   25357 use Import::Into;
  52         164903  
  52         2023  
8              
9 52     52   21750 use Form::Tiny::Form;
  52         220  
  52         2405  
10 52     52   419 use Form::Tiny::Utils qw(:meta_handlers);
  52         137  
  52         21822  
11              
12             sub import
13             {
14 70     70   55022 my ($package, $caller) = (shift, scalar caller);
15              
16 70         538 my @wanted = (-base, @_);
17              
18             # very special case - do something UNLESS -nomoo was passed
19 70 100       372 unless ($package->_get_flag(\@wanted, -nomoo)) {
20 69         501 require Moo;
21 69         568 Moo->import::into($caller);
22             }
23              
24 70         46969 $package->ft_install($caller, @wanted);
25 70         56405 return;
26             }
27              
28             sub ft_install
29             {
30 70     70 0 256 my ($self, $caller, @import_flags) = @_;
31              
32 70         298 my $plugins_flag = $self->_get_flag(\@import_flags, 'plugins', 1);
33 70   100     308 my @plugins = ($self->_get_plugins(\@import_flags), @{$plugins_flag // []});
  70         777  
34              
35             # field context for form building
36 70         500 my $context;
37              
38 70         423 my $wanted = $self->ft_run_plugins($caller, \$context, @plugins);
39              
40             # create metapackage with roles
41 70         154 my $meta = create_form_meta($caller, @{$wanted->{meta_roles}});
  70         437  
42 70         1812 $meta->set_form_roles($wanted->{roles});
43              
44             # install DSL
45             {
46 52     52   451 no strict 'refs';
  52         120  
  52         2938  
  70         1859  
47 52     52   339 no warnings 'redefine';
  52         117  
  52         44148  
48              
49 383         1726 *{"${caller}::$_"} = $wanted->{subs}{$_}
50 70         137 foreach keys %{$wanted->{subs}};
  70         482  
51             }
52              
53 70         561 return \$context;
54             }
55              
56             sub ft_run_plugins
57             {
58 124     124 0 447 my ($self, $caller, $context_ref, @plugins) = @_;
59              
60 124         586 my $wanted = {
61             subs => {},
62             roles => [],
63             meta_roles => [],
64             };
65              
66 124         262 my %seen;
67 124         287 foreach my $plugin (@plugins) {
68 130         455 $plugin = "Form::Tiny::Plugin::$plugin";
69 130         361 $plugin =~ s/^.+\+//;
70 130 100       708 next if $seen{$plugin}++;
71              
72 50     50   28870 my $success = eval "use $plugin; 1";
  50         216  
  50         1129  
  120         11054  
73              
74 120 50       605 croak "could not load plugin $plugin: $@"
75             unless $success;
76 120 50       1024 croak "$plugin is not a Form::Tiny::Plugin"
77             unless $plugin->isa('Form::Tiny::Plugin');
78              
79 120         592 $self->_merge_behaviors($wanted, $plugin->plugin($caller, $context_ref));
80             }
81              
82 124         460 return $wanted;
83             }
84              
85             sub _get_plugins
86             {
87 70     70   185 my ($self, $flags) = @_;
88              
89 70         544 my %known_flags = (
90             -base => ['Base'],
91             -strict => ['Strict'],
92             -filtered => ['Filtered'],
93              
94             # legacy no-op flags
95             -consistent => [],
96             );
97              
98 70         215 my @plugins;
99 70         174 foreach my $flag (@$flags) {
100             croak "no Form::Tiny import behavior for: $flag"
101 115 50       390 unless exists $known_flags{$flag};
102              
103 115         207 push @plugins, @{$known_flags{$flag}};
  115         399  
104             }
105              
106 70         988 return @plugins;
107             }
108              
109             sub _merge_behaviors
110             {
111 120     120   432 my ($self, $wanted, $behaviors) = @_;
112              
113 120   100     236 %{$wanted->{subs}} = (%{$wanted->{subs}}, %{$behaviors->{subs} // {}});
  120         579  
  120         443  
  120         601  
114 120   100     316 push @{$wanted->{roles}}, @{$behaviors->{roles} // []};
  120         253  
  120         519  
115 120   100     228 push @{$wanted->{meta_roles}}, @{$behaviors->{meta_roles} // []};
  120         241  
  120         1121  
116             }
117              
118             sub _get_flag
119             {
120 140     140   432 my ($self, $flags, $wanted, $with_param) = @_;
121 140   100     699 $with_param //= 0;
122              
123 140         537 for my $n (0 .. $#$flags) {
124 244 100       788 if ($flags->[$n] eq $wanted) {
125 6         10 my $param = 1;
126 6 100       20 if ($with_param) {
127 5 50       14 croak "Form::Tiny flag $wanted needs a parameter"
128             if $n == $#$flags;
129 5         13 $param = $flags->[$n + 1];
130             }
131              
132 6         18 splice @$flags, $n, 1 + $with_param;
133 6         20 return $param;
134             }
135             }
136              
137 134         443 return;
138             }
139              
140             1;
141              
142             __END__