Skip to content

Commit

Permalink
conditionals in fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
nics committed Feb 6, 2013
1 parent d703711 commit 6b7f0fa
Show file tree
Hide file tree
Showing 5 changed files with 162 additions and 11 deletions.
6 changes: 3 additions & 3 deletions LICENSE
@@ -1,4 +1,4 @@
This software is copyright (c) 2012 by Nicolas Steenlant <nicolas.steenlant@ugent.be> & Patrick Hochstenbach <patrick.hochstenbach@ugent.be>.
This software is copyright (c) 2013 by Nicolas Steenlant <nicolas.steenlant@ugent.be> & Patrick Hochstenbach <patrick.hochstenbach@ugent.be>.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
Expand All @@ -12,7 +12,7 @@ b) the "Artistic License"

--- The GNU General Public License, Version 1, February 1989 ---

This software is Copyright (c) 2012 by Nicolas Steenlant <nicolas.steenlant@ugent.be> & Patrick Hochstenbach <patrick.hochstenbach@ugent.be>.
This software is Copyright (c) 2013 by Nicolas Steenlant <nicolas.steenlant@ugent.be> & Patrick Hochstenbach <patrick.hochstenbach@ugent.be>.

This is free software, licensed under:

Expand Down Expand Up @@ -272,7 +272,7 @@ That's all there is to it!

--- The Artistic License 1.0 ---

This software is Copyright (c) 2012 by Nicolas Steenlant <nicolas.steenlant@ugent.be> & Patrick Hochstenbach <patrick.hochstenbach@ugent.be>.
This software is Copyright (c) 2013 by Nicolas Steenlant <nicolas.steenlant@ugent.be> & Patrick Hochstenbach <patrick.hochstenbach@ugent.be>.

This is free software, licensed under:

Expand Down
43 changes: 35 additions & 8 deletions lib/Catmandu/Fix.pm
Expand Up @@ -3,27 +3,54 @@ package Catmandu::Fix::Loader;
use Catmandu::Sane;
use Catmandu::Util qw(:is require_package read_file);

my $fixes;
my @fixes;
my @stack;

sub load_fixes {
$fixes = [];
@fixes = ();
@stack = ();
for my $fix (@{$_[0]}) {
if (is_able($fix, 'fix')) {
push @$fixes, $fix;
push @fixes, $fix;
} elsif (is_string($fix)) {
if (-r $fix) {
$fix = read_file($fix);
}
eval "package Catmandu::Fix::Loader::Env;$fix;1" or confess $@;
}
}
$fixes;
confess "if without end" if @stack;
[@fixes];
}

sub add_fix {
sub _add_fix {
my ($fix, @args) = @_;
$fix = require_package($fix, 'Catmandu::Fix');
push @$fixes, $fix->new(@args);

if ($fix eq 'end') {
$fix = pop @stack || confess "end without if";
if (@stack) {
push @{$stack[-1]->fixes}, $fix;
} else {
push @fixes, $fix;
}
}
elsif ($fix =~ s/^if_//) {
$fix = require_package($fix, 'Catmandu::FixCondition')->new(@args);
push @stack, $fix;
}
elsif ($fix =~ s/^unless_//) {
$fix = require_package($fix, 'Catmandu::FixCondition')->new(@args);
$fix->invert(1);
push @stack, $fix;
}
else {
$fix = require_package($fix, 'Catmandu::Fix')->new(@args);
if (@stack) {
push @{$stack[-1]->fixes}, $fix;
} else {
push @fixes, $fix;
}
}
}

package Catmandu::Fix::Loader::Env;
Expand All @@ -34,7 +61,7 @@ use warnings;
sub AUTOLOAD {
my ($fix) = our $AUTOLOAD =~ /::(\w+)$/;

my $sub = sub { Catmandu::Fix::Loader::add_fix($fix, @_); return };
my $sub = sub { Catmandu::Fix::Loader::_add_fix($fix, @_); return };

{ no strict 'refs'; *$AUTOLOAD = $sub };

Expand Down
28 changes: 28 additions & 0 deletions lib/Catmandu/FixCondition.pm
@@ -0,0 +1,28 @@
package Catmandu::FixCondition;

use Catmandu::Sane;
use Moo::Role;

requires 'is_fixable';

has fixes => (is => 'ro', default => sub { [] });
has invert => (is => 'rw');

sub fix {
my ($self, $data) = @_;

my $ok = $self->is_fixable($data);
if ($self->invert) {
$ok = !$ok;
}

if ($ok) {
for my $fix (@{$self->fixes}) {
$data = $fix->fix($data);
}
}

$data
}

1;
48 changes: 48 additions & 0 deletions lib/Catmandu/FixCondition/any_match.pm
@@ -0,0 +1,48 @@
package Catmandu::FixCondition::any_match;

use Catmandu::Sane;
use Catmandu::Util qw(:data);
use Moo;

with 'Catmandu::FixCondition';

has path => (is => 'ro', required => 1);
has key => (is => 'ro', required => 1);
has pattern => (is => 'ro', required => 1);

around BUILDARGS => sub {
my ($orig, $class, $path, $pattern) = @_;
my ($p, $key) = parse_data_path($path);
$orig->($class, path => $p, key => $key, pattern => $pattern);
};

sub is_fixable {
my ($self, $data) = @_;
my $key = $self->key;
my $pattern = $self->pattern;
for my $match (grep ref, data_at($self->path, $data)) {
for my $val (get_data($match, $key)) {
return 1 if $val =~ m{$pattern};
}
}
0;
}

=head1 NAME
Catmandu::FixCondition::any_match - only execute fixes if any path value matches the given regex
=head1 SYNOPSIS
# uppercase the value of field 'foo' if field 'oogly' has the value 'doogly'
if_any_match('oogly', 'doogly');
upcase('foo'); # foo => 'BAR'
end()
=head1 SEE ALSO
L<Catmandu::Fix>
=cut

1;
48 changes: 48 additions & 0 deletions lib/Catmandu/FixCondition/exists.pm
@@ -0,0 +1,48 @@
package Catmandu::FixCondition::exists;

use Catmandu::Sane;
use Catmandu::Util qw(:data);
use Moo;

with 'Catmandu::FixCondition';

has path => (is => 'ro', required => 1);
has key => (is => 'ro', required => 1);

around BUILDARGS => sub {
my ($orig, $class, $path) = @_;
my ($p, $key) = parse_data_path($path);
$orig->($class, path => $p, key => $key);
};

sub is_fixable {
my ($self, $data) = @_;
my $key = $self->key;
for my $match (grep ref, data_at($self->path, $data)) {
return 1 if get_data($match, $key);
}
0;
}

=head1 NAME
Catmandu::FixCondition::exists - only execute fixes if the path exists
=head1 SYNOPSIS
# uppercase the value of field 'foo' if the field 'oogly' exists
if_exists('oogly');
upcase('foo'); # foo => 'BAR'
end()
# inverted
unless_exists('oogly');
upcase('foo'); # foo => 'bar'
end()
=head1 SEE ALSO
L<Catmandu::Fix>
=cut

1;

0 comments on commit 6b7f0fa

Please sign in to comment.