File: | local/lib/perl5/Data/OptList.pm |
Coverage: | 85.2% |
line | stmt | bran | cond | sub | time | code |
---|---|---|---|---|---|---|
1 | 6 6 6 | 11 5 77 | use strict; | |||
2 | 6 6 6 | 11 3 114 | use warnings; | |||
3 | package Data::OptList; | |||||
4 | { | |||||
5 | $Data::OptList::VERSION = '0.109'; | |||||
6 | } | |||||
7 | # ABSTRACT: parse and validate simple name/value option pairs | |||||
8 | ||||||
9 | 6 6 6 | 11 5 28 | use List::Util (); | |||
10 | 6 6 6 | 865 4 70 | use Params::Util (); | |||
11 | 6 6 6 | 699 65 138 | use Sub::Install 0.921 (); | |||
12 | ||||||
13 | ||||||
14 | my %test_for; | |||||
15 | BEGIN { | |||||
16 | 6 | 1459 | %test_for = ( | |||
17 | CODE => \&Params::Util::_CODELIKE, ## no critic | |||||
18 | HASH => \&Params::Util::_HASHLIKE, ## no critic | |||||
19 | ARRAY => \&Params::Util::_ARRAYLIKE, ## no critic | |||||
20 | SCALAR => \&Params::Util::_SCALAR0, ## no critic | |||||
21 | ); | |||||
22 | } | |||||
23 | ||||||
24 | sub __is_a { | |||||
25 | 42 | 19 | my ($got, $expected) = @_; | |||
26 | ||||||
27 | 42 24 | 101 27 | return List::Util::first { __is_a($got, $_) } @$expected if ref $expected; | |||
28 | ||||||
29 | return defined ( | |||||
30 | 24 | 69 | exists($test_for{$expected}) | |||
31 | ? $test_for{$expected}->($got) | |||||
32 | : Params::Util::_INSTANCE($got, $expected) ## no critic | |||||
33 | ); | |||||
34 | } | |||||
35 | ||||||
36 | sub mkopt { | |||||
37 | 40 | 27 | my ($opt_list) = shift; | |||
38 | ||||||
39 | 40 | 20 | my ($moniker, $require_unique, $must_be); # the old positional args | |||
40 | 0 | 0 | my $name_test; | |||
41 | ||||||
42 | 40 | 57 | if (@_ == 1 and Params::Util::_HASHLIKE($_[0])) { | |||
43 | 0 | 0 | my $arg = $_[0]; | |||
44 | 0 | 0 | ($moniker, $require_unique, $must_be, $name_test) | |||
45 | = @$arg{ qw(moniker require_unique must_be name_test) }; | |||||
46 | } else { | |||||
47 | 40 | 31 | ($moniker, $require_unique, $must_be) = @_; | |||
48 | } | |||||
49 | ||||||
50 | 40 | 43 | $moniker = 'unnamed' unless defined $moniker; | |||
51 | ||||||
52 | 40 | 30 | return [] unless $opt_list; | |||
53 | ||||||
54 | 40 84 | 94 73 | $name_test ||= sub { ! ref $_[0] }; | |||
55 | ||||||
56 | 12 | 26 | $opt_list = [ | |||
57 | 40 | 56 | map { $_ => (ref $opt_list->{$_} ? $opt_list->{$_} : ()) } keys %$opt_list | |||
58 | ] if ref $opt_list eq 'HASH'; | |||||
59 | ||||||
60 | 40 | 19 | my @return; | |||
61 | my %seen; | |||||
62 | ||||||
63 | 40 | 50 | for (my $i = 0; $i < @$opt_list; $i++) { ## no critic | |||
64 | 96 | 48 | my $name = $opt_list->[$i]; | |||
65 | 96 | 40 | my $value; | |||
66 | ||||||
67 | 96 | 66 | if ($require_unique) { | |||
68 | 72 | 77 | Carp::croak "multiple definitions provided for $name" if $seen{$name}++; | |||
69 | } | |||||
70 | ||||||
71 | 96 12 | 136 9 | if ($i == $#$opt_list) { $value = undef; } | |||
72 | 0 0 | 0 0 | elsif (not defined $opt_list->[$i+1]) { $value = undef; $i++ } | |||
73 | 60 | 30 | elsif ($name_test->($opt_list->[$i+1])) { $value = undef; } | |||
74 | 24 | 11 | else { $value = $opt_list->[++$i] } | |||
75 | ||||||
76 | 96 | 143 | if ($must_be and defined $value) { | |||
77 | 18 | 20 | unless (__is_a($value, $must_be)) { | |||
78 | 0 | 0 | my $ref = ref $value; | |||
79 | 0 | 0 | Carp::croak "$ref-ref values are not valid in $moniker opt list"; | |||
80 | } | |||||
81 | } | |||||
82 | ||||||
83 | 96 | 152 | push @return, [ $name => $value ]; | |||
84 | } | |||||
85 | ||||||
86 | 40 | 70 | return \@return; | |||
87 | } | |||||
88 | ||||||
89 | ||||||
90 | sub mkopt_hash { | |||||
91 | 36 | 29 | my ($opt_list, $moniker, $must_be) = @_; | |||
92 | 36 | 49 | return {} unless $opt_list; | |||
93 | ||||||
94 | 24 | 18 | $opt_list = mkopt($opt_list, $moniker, 1, $must_be); | |||
95 | 24 72 | 19 69 | my %hash = map { $_->[0] => $_->[1] } @$opt_list; | |||
96 | 24 | 49 | return \%hash; | |||
97 | } | |||||
98 | ||||||
99 | ||||||
100 | BEGIN { | |||||
101 | 6 | 15 | *import = Sub::Install::exporter { | |||
102 | exports => [qw(mkopt mkopt_hash)], | |||||
103 | }; | |||||
104 | } | |||||
105 | ||||||
106 | 1; | |||||
107 |