Hash-Match
view release on metacpan or search on metacpan
lib/Hash/Match.pm view on Meta::CPAN
package Hash::Match;
# ABSTRACT: match contents of a hash against rules
use v5.14;
use warnings;
our $VERSION = 'v0.8.2';
use Carp qw/ croak /;
use List::AllUtils qw/ natatime /;
use Ref::Util qw/ is_arrayref is_blessed_ref is_coderef is_hashref is_ref is_regexpref /;
# RECOMMEND PREREQ: List::SomeUtils::XS
# RECOMMEND PREREQ: Ref::Util::XS
use namespace::autoclean;
sub new {
my ($class, %args) = @_;
if (my $rules = $args{rules}) {
my $root = is_hashref($rules) ? '-all' : '-any';
my $self = _compile_rule( $root => $rules, $class );
bless $self, $class;
} else {
croak "Missing 'rules' attribute";
}
}
sub _compile_match {
my ($value) = @_;
if ( is_ref($value) ) {
return sub { ($_[0] // '') =~ $value } if is_regexpref($value);
return sub { $value->($_[0]) } if is_coderef($value);
croak sprintf('Unsupported type: \'%s\'', ref $value);
} else {
return sub { ($_[0] // '') eq $value } if (defined $value);
return sub { !defined $_[0] };
}
}
sub _key2fn {
my ($key, $is_hash) = @_;
state $KEY2FN = {
'-all' => List::AllUtils->can('all'),
'-and' => List::AllUtils->can('all'),
'-any' => List::AllUtils->can('any'),
'-notall' => List::AllUtils->can('notall'),
'-notany' => List::AllUtils->can('none'),
'-or' => List::AllUtils->can('any'),
};
# TODO: eventually add a warning message about -not being
# deprecated.
if ($key eq '-not') {
$key = $is_hash ? '-notall' : '-notany';
}
$KEY2FN->{$key} or croak "Unsupported key: '${key}'";
( run in 0.687 second using v1.01-cache-2.11-cpan-39bf76dae61 )