| 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 | ||||||