use
5.008001;
BEGIN {
$Types::Standard::ArrayRef::AUTHORITY
=
'cpan:TOBYINK'
;
$Types::Standard::ArrayRef::VERSION
=
'2.008001'
;
}
$Types::Standard::ArrayRef::VERSION
=~
tr
/_//d;
sub
_croak ($;@) {
require
Error::TypeTiny;
goto
\
&Error::TypeTiny::croak
}
our
@ISA
=
qw( Exporter::Tiny )
;
sub
_exporter_fail {
my
(
$class
,
$type_name
,
$values
,
$globals
) =
@_
;
my
$caller
=
$globals
->{into};
my
$of
=
exists
(
$values
->{of} ) ?
$values
->{of} :
$values
->{type};
defined
$of
or _croak(
qq{Expected option "of" for type "$type_name"}
);
if
( not Types::TypeTiny::is_TypeTiny(
$of
) ) {
$of
= Type::Utils::dwim_type(
$of
,
for
=>
$caller
);
}
my
$type
= Types::Standard::ArrayRef->of(
$of
);
$type
=
$type
->create_child_type(
name
=>
$type_name
,
$type
->has_coercion ? (
coercion
=> 1 ) : (),
exists
(
$values
->{where} ) ? (
constraint
=>
$values
->{where} ) : (),
);
$INC
{
'Type/Registry.pm'
}
?
'Type::Registry'
->for_class(
$caller
)->add_type(
$type
,
$type_name
)
: (
$Type::Registry::DELAYED
{
$caller
}{
$type_name
} =
$type
)
unless
(
ref
(
$caller
) or
$caller
eq
'-lexical'
or
$globals
->{
'lexical'
} );
return
map
+(
$_
->{name} =>
$_
->{code} ), @{
$type
->exportables };
}
no
warnings;
sub
__constraint_generator {
return
Types::Standard::ArrayRef
unless
@_
;
Type::Tiny::check_parameter_count_for_parameterized_type(
'Types::Standard'
,
'ArrayRef'
, \
@_
, 3 );
my
$param
=
shift
;
Types::TypeTiny::is_TypeTiny(
$param
)
or _croak(
"Parameter to ArrayRef[`a] expected to be a type constraint; got $param"
);
my
(
$min
,
$max
) = ( 0, -1 );
$min
= Types::Standard::assert_Int(
shift
)
if
@_
;
$max
= Types::Standard::assert_Int(
shift
)
if
@_
;
my
$param_compiled_check
=
$param
->compiled_check;
my
$xsub
;
if
( Type::Tiny::_USE_XS and
$min
== 0 and
$max
== -1 ) {
my
$paramname
= Type::Tiny::XS::is_known(
$param_compiled_check
);
$xsub
= Type::Tiny::XS::get_coderef_for(
"ArrayRef[$paramname]"
)
if
$paramname
;
}
elsif
( Type::Tiny::_USE_MOUSE
and
$param
->_has_xsub
and
$min
== 0
and
$max
== -1 )
{
my
$maker
=
"Mouse::Util::TypeConstraints"
->can(
"_parameterize_ArrayRef_for"
);
$xsub
=
$maker
->(
$param
)
if
$maker
;
}
return
(
sub
{
my
$array
=
shift
;
$param
->check(
$_
) ||
return
for
@$array
;
return
!!1;
},
$xsub
,
)
if
$min
== 0 and
$max
== -1;
return
sub
{
my
$array
=
shift
;
return
if
@$array
<
$min
;
$param
->check(
$_
) ||
return
for
@$array
;
return
!!1;
}
if
$max
== -1;
return
sub
{
my
$array
=
shift
;
return
if
@$array
>
$max
;
$param
->check(
$_
) ||
return
for
@$array
;
return
!!1;
}
if
$min
== 0;
return
sub
{
my
$array
=
shift
;
return
if
@$array
<
$min
;
return
if
@$array
>
$max
;
$param
->check(
$_
) ||
return
for
@$array
;
return
!!1;
};
}
sub
__inline_generator {
my
$param
=
shift
;
my
(
$min
,
$max
) = ( 0, -1 );
$min
=
shift
if
@_
;
$max
=
shift
if
@_
;
my
$param_compiled_check
=
$param
->compiled_check;
my
$xsubname
;
if
( Type::Tiny::_USE_XS and
$min
== 0 and
$max
== -1 ) {
my
$paramname
= Type::Tiny::XS::is_known(
$param_compiled_check
);
$xsubname
= Type::Tiny::XS::get_subname_for(
"ArrayRef[$paramname]"
);
}
return
unless
$param
->can_be_inlined;
return
sub
{
my
$v
=
$_
[1];
return
"$xsubname\($v\)"
if
$xsubname
&& !
$Type::Tiny::AvoidCallbacks
;
my
$p
= Types::Standard::ArrayRef->inline_check(
$v
);
if
(
$min
!= 0 ) {
$p
.=
sprintf
(
' and @{%s} >= %d'
,
$v
,
$min
);
}
if
(
$max
> 0 ) {
$p
.=
sprintf
(
' and @{%s} <= %d'
,
$v
,
$max
);
}
my
$param_check
=
$param
->inline_check(
'$i'
);
return
$p
if
$param
->{uniq} eq Types::Standard::Any->{uniq};
"$p and do { "
.
"my \$ok = 1; "
.
"for my \$i (\@{$v}) { "
.
"(\$ok = 0, last) unless $param_check "
.
"}; "
.
"\$ok "
.
"}"
;
};
}
sub
__deep_explanation {
my
(
$type
,
$value
,
$varname
) =
@_
;
my
$param
=
$type
->parameters->[0];
my
(
$min
,
$max
) = ( 0, -1 );
$min
=
$type
->parameters->[1]
if
@{
$type
->parameters } > 1;
$max
=
$type
->parameters->[2]
if
@{
$type
->parameters } > 2;
if
(
$min
!= 0 and
@$value
<
$min
) {
return
[
sprintf
(
'"%s" constrains array length at least %s'
,
$type
,
$min
),
sprintf
(
'@{%s} is %d'
,
$varname
,
scalar
@$value
),
];
}
if
(
$max
> 0 and
@$value
>
$max
) {
return
[
sprintf
(
'"%s" constrains array length at most %d'
,
$type
,
$max
),
sprintf
(
'@{%s} is %d'
,
$varname
,
scalar
@$value
),
];
}
for
my
$i
( 0 ..
$#$value
) {
my
$item
=
$value
->[
$i
];
next
if
$param
->check(
$item
);
return
[
sprintf
(
'"%s" constrains each value in the array with "%s"'
,
$type
,
$param
),
@{
$param
->validate_explain(
$item
,
sprintf
(
'%s->[%d]'
,
$varname
,
$i
) ) },
];
}
return
;
}
sub
__coercion_generator {
my
(
$parent
,
$child
,
$param
) =
@_
;
return
unless
$param
->has_coercion;
my
$coercable_item
=
$param
->coercion->_source_type_union;
my
$C
=
"Type::Coercion"
->new(
type_constraint
=>
$child
);
if
(
$param
->coercion->can_be_inlined and
$coercable_item
->can_be_inlined ) {
$C
->add_type_coercions(
$parent
=> Types::Standard::Stringable {
my
@code
;
push
@code
,
'do { my ($orig, $return_orig, @new) = ($_, 0);'
;
push
@code
,
'for (@$orig) {'
;
push
@code
,
sprintf
(
'++$return_orig && last unless (%s);'
,
$coercable_item
->inline_check(
'$_'
)
);
push
@code
,
sprintf
(
'push @new, (%s);'
,
$param
->coercion->inline_coercion(
'$_'
)
);
push
@code
,
'}'
;
push
@code
,
'$return_orig ? $orig : \\@new'
;
push
@code
,
'}'
;
"@code"
;
}
);
}
else
{
$C
->add_type_coercions(
$parent
=>
sub
{
my
$value
=
@_
?
$_
[0] :
$_
;
my
@new
;
for
my
$item
(
@$value
) {
return
$value
unless
$coercable_item
->check(
$item
);
push
@new
,
$param
->coerce(
$item
);
}
return
\
@new
;
},
);
}
return
$C
;
}
1;