Iterator-Flex

 view release on metacpan or  search on metacpan

lib/Iterator/Flex/Role/Wrap/Throw.pm  view on Meta::CPAN

package Iterator::Flex::Role::Wrap::Throw;

# ABSTRACT: Role to add throw on exhaustion to an iterator which adapts another iterator

use v5.28;
use strict;
use warnings;

our $VERSION = '0.34';

use List::Util 'first';
use Iterator::Flex::Utils qw( INPUT_EXHAUSTION PASSTHROUGH );
use Ref::Util             qw( is_ref is_blessed_ref is_regexpref is_arrayref is_coderef );
use Role::Tiny;
use experimental 'signatures';

use namespace::clean;

around _construct_next => sub ( $orig, $class, $ipar, $gpar ) {

    my $next = $class->$orig( $ipar, $gpar );

    my $exception = (
        $gpar->{ +INPUT_EXHAUSTION } // do {
            require Iterator::Flex::Failure;
            Iterator::Flex::Failure::parameter->throw(
                q{internal error: input exhaustion policy was not registered} );
        }
    )->[1];

    my $wsub;

    ## no critic ( CascadingIfElse )
    if ( !defined $exception ) {

        $wsub = sub {
            my $self = $_[0] // $wsub;
            my $val  = eval { $next->( $self ) };
            return $@ ne q{} ? $self->signal_exhaustion( $@ ) : $val;
        };
    }

    elsif ( !is_ref( $exception ) && $exception eq PASSTHROUGH ) {

        $wsub = sub {
            my $self = $_[0] // $wsub;
            my $val  = eval { $next->( $self ) };
            return $@ ne q{} ? $self->signal_exhaustion( $@ ) : $val;
        };
    }

    elsif ( !is_ref( $exception ) || is_arrayref( $exception ) ) {
        $exception = [$exception]
          unless is_arrayref( $exception );

        $wsub = sub {
            my $self = $_[0] // $wsub;
            my $val  = eval { $next->( $self ) };
            if ( $@ ne q{} ) {
                my $e = $@;
                return $self->signal_exhaustion( $e )
                  if is_blessed_ref( $e ) && first { $e->isa( $_ ) } @$exception;
                die $e;
            }
            return $val;
        };
    }

    elsif ( is_regexpref( $exception ) ) {

        $wsub = sub {
            my $self = $_[0] // $wsub;
            my $val  = eval { $next->( $self ) };



( run in 1.411 second using v1.01-cache-2.11-cpan-5735350b133 )