package Catmandu::Fix::Loader::Env;
use strict;
use warnings FATAL => 'all';
sub AUTOLOAD {
my ($fix) = our $AUTOLOAD =~ /::(\w+)$/;
my $sub = sub { Catmandu::Fix::Loader::_add_fix($fix, @_); return };
{ no strict 'refs'; *$AUTOLOAD = $sub };
$sub->(@_);
}
sub DESTROY {}
package Catmandu::Fix::Loader;
use Catmandu::Sane;
use Catmandu::Util qw(:is require_package read_file);
my @fixes;
my @stack;
sub load_fixes {
@fixes = ();
@stack = ();
for my $fix (@{$_[0]}) {
if (is_able($fix, 'fix')) {
push @fixes, $fix;
} elsif (is_string($fix)) {
if (-r $fix) {
$fix = read_file($fix);
}
eval "package Catmandu::Fix::Loader::Env;$fix;1" or Catmandu::BadArg->throw("can't load fix $fix: $@");
}
}
Catmandu::BadArg->throw("if without end") if @stack;
[@fixes];
}
sub _add_fix {
my ($fix, @args) = @_;
if ($fix eq 'end') {
$fix = pop @stack || Catmandu::BadArg->throw("end without if");
if (@stack) {
push @{$stack[-1]->fixes}, $fix;
} else {
push @fixes, $fix;
}
}
elsif ($fix =~ s/^if_//) {
$fix = require_package($fix, 'Catmandu::Fix::Condition')->new(@args);
push @stack, $fix;
}
elsif ($fix =~ s/^unless_//) {
$fix = require_package($fix, 'Catmandu::Fix::Condition')->new(@args);
$fix->invert(1);
push @stack, $fix;
}
elsif ($fix =~ /^[a-z]/) {
$fix = require_package($fix, 'Catmandu::Fix')->new(@args);
if (@stack) {
push @{$stack[-1]->fixes}, $fix;
} else {
push @fixes, $fix;
}
}
else {
Catmandu::BadArg->throw("invalid fix name");
}
}
1;