package HTML::FormFu::Role::Element::Coercible;
$HTML::FormFu::Role::Element::Coercible::VERSION = '2.00';
use Moose::Role;
use Carp qw( croak );
use HTML::FormFu::Util qw( require_class );
sub as {
my ( $self, $type, %attrs ) = @_;
return $self->_coerce(
type => $type,
attributes => \%attrs,
errors => $self->_errors,
package => __PACKAGE__,
);
}
sub _coerce {
my ( $self, %args ) = @_;
for (qw( type attributes package )) {
croak "$_ argument required" if !defined $args{$_};
}
my $class = $args{type};
if ( $class !~ /^\+/ ) {
$class = "HTML::FormFu::Element::$class";
}
require_class($class);
my $element = $class->new( { type => $args{type}, } );
for my $method ( qw(
name
attributes comment
comment_attributes label
label_attributes label_filename
render_method parent
) )
{
$element->$method( $self->$method );
}
_coerce_processors_and_errors( $self, $element, %args );
$element->attributes( $args{attributes} );
croak "element cannot be coerced to type '$args{type}'"
unless $element->isa( $args{package} )
|| $element->does( $args{package} );
$element->value( $self->value );
return $element;
}
sub _coerce_processors_and_errors {
my ( $self, $element, %args ) = @_;
if ( $args{errors} && @{ $args{errors} } > 0 ) {
my @errors = @{ $args{errors} };
my @new_errors;
for my $list ( qw(
_filters _constraints
_inflators _validators
_transformers _deflators
) )
{
$element->$list( [] );
for my $processor ( @{ $self->$list } ) {
my @errors_to_copy = map { $_->clone }
grep { $_->processor == $processor } @errors;
my $processor_clone = $processor->clone;
$processor_clone->parent($element);
map { $_->processor($processor_clone) } @errors_to_copy;
push @{ $element->$list }, $processor_clone;
push @new_errors, @errors_to_copy;
}
}
$element->_errors( \@new_errors );
}
else {
$element->_errors( [] );
}
return;
}
1;