use
5.008001;
our
$AUTHORITY
=
'cpan:TOBYINK'
;
our
$VERSION
=
'2.008000'
;
$VERSION
=~
tr
/_//d;
BEGIN {
*__XS
=
eval
{
'Type::Tiny::XS'
->VERSION(
'0.022'
);
1;
}
?
eval
"sub () { '$Type::Tiny::XS::VERSION' }"
:
sub
() { !!0 };
}
our
@EXPORT_OK
= (
map
( @{ [
$_
,
"is_$_"
,
"assert_$_"
] }, __PACKAGE__->type_names ),
qw/to_TypeTiny/
);
our
%EXPORT_TAGS
= (
types
=> [ __PACKAGE__->type_names ],
is
=> [
map
"is_$_"
, __PACKAGE__->type_names ],
assert
=> [
map
"assert_$_"
, __PACKAGE__->type_names ],
);
my
%cache
;
sub
import
{
return
unless
@_
> 1;
no
warnings
"redefine"
;
our
@ISA
=
qw( Exporter::Tiny )
;
my
$next
= \
&Exporter::Tiny::import
;
*import
=
$next
;
my
$class
=
shift
;
my
$opts
= {
ref
(
$_
[0] ) ? %{ +
shift
} : () };
$opts
->{into} ||=
scalar
(
caller
);
_mkall();
return
$class
->
$next
(
$opts
,
@_
);
}
for
( __PACKAGE__->type_names ) {
eval
qq{ # uncoverable statement
sub is_$_ { $_()->check(shift) }
sub
assert_
$_
{
$_
()->assert_return(
shift
) }
};
}
sub
_reinstall_subs {
my
$type
=
shift
;
no
strict
'refs'
;
no
warnings
'redefine'
;
*{
'is_'
.
$type
->name } =
$type
->compiled_check;
*{
'assert_'
.
$type
->name } = \
&$type
;
$type
;
}
sub
_mkall {
return
unless
$INC
{
'Type/Tiny.pm'
};
__PACKAGE__->get_type(
$_
)
for
__PACKAGE__->type_names;
}
sub
meta {
return
$_
[0];
}
sub
type_names {
qw(
StringLike BoolLike
HashLike ArrayLike CodeLike
TypeTiny _ForeignTypeConstraint
)
;
}
sub
has_type {
my
%has
=
map
+(
$_
=> 1 ),
shift
->type_names;
!!
$has
{
$_
[0] };
}
sub
get_type {
my
$self
=
shift
;
return
unless
$self
->has_type(
@_
);
no
strict
qw(refs)
;
&{
$_
[0] }();
}
sub
coercion_names {
qw()
;
}
sub
has_coercion {
my
%has
=
map
+(
$_
=> 1 ),
shift
->coercion_names;
!!
$has
{
$_
[0] };
}
sub
get_coercion {
my
$self
=
shift
;
return
unless
$self
->has_coercion(
@_
);
no
strict
qw(refs)
;
&{
$_
[0] }();
}
my
(
$__get_linear_isa_dfs
,
$tried_mro
);
$__get_linear_isa_dfs
=
sub
{
if
( !
$tried_mro
&&
eval
{
require
mro } ) {
$__get_linear_isa_dfs
= \
&mro::get_linear_isa
;
goto
$__get_linear_isa_dfs
;
}
no
strict
'refs'
;
my
$classname
=
shift
;
my
@lin
= (
$classname
);
my
%stored
;
foreach
my
$parent
( @{
"$classname\::ISA"
} ) {
my
$plin
=
$__get_linear_isa_dfs
->(
$parent
);
foreach
(
@$plin
) {
next
if
exists
$stored
{
$_
};
push
(
@lin
,
$_
);
$stored
{
$_
} = 1;
}
}
return
\
@lin
;
};
sub
_check_overload {
my
$package
=
shift
;
if
(
ref
$package
) {
$package
= blessed(
$package
);
return
!!0
if
!
defined
$package
;
}
my
$op
=
shift
;
my
$mro
=
$__get_linear_isa_dfs
->(
$package
);
foreach
my
$p
(
@$mro
) {
my
$fqmeth
=
$p
.
q{::(}
.
$op
;
return
!!1
if
defined
&{
$fqmeth
};
}
!!0;
}
sub
_get_check_overload_sub {
if
(
$Type::Tiny::AvoidCallbacks
) {
return
'(sub { require overload; overload::Overloaded(ref $_[0] or $_[0]) and overload::Method((ref $_[0] or $_[0]), $_[1]) })->'
;
}
return
'Types::TypeTiny::_check_overload'
;
}
sub
StringLike () {
return
$cache
{StringLike}
if
defined
$cache
{StringLike};
my
%common
= (
name
=>
"StringLike"
,
library
=> __PACKAGE__,
constraint
=>
sub
{
defined
(
$_
) && !
ref
(
$_
)
or blessed(
$_
) && _check_overload(
$_
,
q[""]
);
},
inlined
=>
sub
{
qq/defined($_[1]) && !ref($_[1]) or Scalar::Util::blessed($_[1]) && ${\ +_get_check_overload_sub() }($_[1], q[""])/
;
},
type_default
=>
sub
{
return
''
},
);
if
( __XS ) {
my
$xsub
= Type::Tiny::XS::get_coderef_for(
'StringLike'
);
my
$xsubname
= Type::Tiny::XS::get_subname_for(
'StringLike'
);
my
$inlined
=
$common
{inlined};
$cache
{StringLike} =
"Type::Tiny"
->new(
%common
,
compiled_type_constraint
=>
$xsub
,
inlined
=>
sub
{
(
$Type::Tiny::AvoidCallbacks
or not
$xsubname
)
?
goto
(
$inlined
)
:
qq/$xsubname($_[1])/
},
);
_reinstall_subs
$cache
{StringLike};
}
else
{
$cache
{StringLike} =
"Type::Tiny"
->new(
%common
);
}
}
sub
HashLike (;@) {
return
$cache
{HashLike}
if
defined
(
$cache
{HashLike} ) && !
@_
;
my
%common
= (
name
=>
"HashLike"
,
library
=> __PACKAGE__,
constraint
=>
sub
{
ref
(
$_
) eq
q[HASH]
or blessed(
$_
) && _check_overload(
$_
,
q[%{}]
);
},
inlined
=>
sub
{
qq/ref($_[1]) eq q[HASH] or Scalar::Util::blessed($_[1]) && ${\ +_get_check_overload_sub() }($_[1], q[\%{}])/
;
},
type_default
=>
sub
{
return
{} },
constraint_generator
=>
sub
{
my
$param
= TypeTiny()->assert_coerce(
shift
);
my
$check
=
$param
->compiled_check;
if
( __XS ge
'0.025'
) {
my
$paramname
= Type::Tiny::XS::is_known(
$check
);
my
$xsub
=
defined
(
$paramname
)
? Type::Tiny::XS::get_coderef_for(
"HashLike[$paramname]"
)
:
undef
;
return
$xsub
if
$xsub
;
}
sub
{
my
%hash
=
%$_
;
for
my
$key
(
sort
keys
%hash
) {
$check
->(
$hash
{
$key
} ) or
return
0;
}
return
1;
};
},
inline_generator
=>
sub
{
my
$param
= TypeTiny()->assert_coerce(
shift
);
return
unless
$param
->can_be_inlined;
my
$check
=
$param
->compiled_check;
my
$xsubname
;
if
( __XS ge
'0.025'
) {
my
$paramname
= Type::Tiny::XS::is_known(
$check
);
$xsubname
=
defined
(
$paramname
)
? Type::Tiny::XS::get_subname_for(
"HashLike[$paramname]"
)
:
undef
;
}
sub
{
my
$var
=
pop
;
return
"$xsubname($var)"
if
$xsubname
&& !
$Type::Tiny::AvoidCallbacks
;
my
$code
=
sprintf
(
'do { my $ok=1; my %%h = %%{%s}; for my $k (sort keys %%h) { ($ok=0,next) unless (%s) }; $ok }'
,
$var
,
$param
->inline_check(
'$h{$k}'
),
);
return
(
undef
,
$code
);
};
},
coercion_generator
=>
sub
{
my
(
$parent
,
$child
,
$param
) =
@_
;
return
unless
$param
->has_coercion;
my
$coercible
=
$param
->coercion->_source_type_union->compiled_check;
my
$C
=
"Type::Coercion"
->new(
type_constraint
=>
$child
);
$C
->add_type_coercions(
$parent
=>
sub
{
my
$origref
=
@_
?
$_
[0] :
$_
;
my
%orig
=
%$origref
;
my
%new
;
for
my
$k
(
sort
keys
%orig
) {
return
$origref
unless
$coercible
->(
$orig
{
$k
} );
$new
{
$k
} =
$param
->coerce(
$orig
{
$k
} );
}
\
%new
;
},
);
return
$C
;
},
);
if
( __XS ) {
my
$xsub
= Type::Tiny::XS::get_coderef_for(
'HashLike'
);
my
$xsubname
= Type::Tiny::XS::get_subname_for(
'HashLike'
);
my
$inlined
=
$common
{inlined};
$cache
{HashLike} =
"Type::Tiny"
->new(
%common
,
compiled_type_constraint
=>
$xsub
,
inlined
=>
sub
{
(
$Type::Tiny::AvoidCallbacks
or not
$xsubname
)
?
goto
(
$inlined
)
:
qq/$xsubname($_[1])/
},
);
_reinstall_subs
$cache
{HashLike};
}
else
{
$cache
{HashLike} =
"Type::Tiny"
->new(
%common
);
}
@_
?
$cache
{HashLike}->parameterize( @{
$_
[0] } ) :
$cache
{HashLike};
}
sub
ArrayLike (;@) {
return
$cache
{ArrayLike}
if
defined
(
$cache
{ArrayLike} ) && !
@_
;
my
%common
= (
name
=>
"ArrayLike"
,
library
=> __PACKAGE__,
constraint
=>
sub
{
ref
(
$_
) eq
q[ARRAY]
or blessed(
$_
) && _check_overload(
$_
,
q[@{}]
);
},
inlined
=>
sub
{
qq/ref($_[1]) eq q[ARRAY] or Scalar::Util::blessed($_[1]) && ${\ +_get_check_overload_sub() }($_[1], q[\@{}])/
;
},
type_default
=>
sub
{
return
[] },
constraint_generator
=>
sub
{
my
$param
= TypeTiny()->assert_coerce(
shift
);
my
$check
=
$param
->compiled_check;
if
( __XS ge
'0.025'
) {
my
$paramname
= Type::Tiny::XS::is_known(
$check
);
my
$xsub
=
defined
(
$paramname
)
? Type::Tiny::XS::get_coderef_for(
"ArrayLike[$paramname]"
)
:
undef
;
return
$xsub
if
$xsub
;
}
sub
{
my
@arr
=
@$_
;
for
my
$val
(
@arr
) {
$check
->(
$val
) or
return
0;
}
return
1;
};
},
inline_generator
=>
sub
{
my
$param
= TypeTiny()->assert_coerce(
shift
);
return
unless
$param
->can_be_inlined;
my
$check
=
$param
->compiled_check;
my
$xsubname
;
if
( __XS ge
'0.025'
) {
my
$paramname
= Type::Tiny::XS::is_known(
$check
);
$xsubname
=
defined
(
$paramname
)
? Type::Tiny::XS::get_subname_for(
"ArrayLike[$paramname]"
)
:
undef
;
}
sub
{
my
$var
=
pop
;
return
"$xsubname($var)"
if
$xsubname
&& !
$Type::Tiny::AvoidCallbacks
;
my
$code
=
sprintf
(
'do { my $ok=1; for my $v (@{%s}) { ($ok=0,next) unless (%s) }; $ok }'
,
$var
,
$param
->inline_check(
'$v'
),
);
return
(
undef
,
$code
);
};
},
coercion_generator
=>
sub
{
my
(
$parent
,
$child
,
$param
) =
@_
;
return
unless
$param
->has_coercion;
my
$coercible
=
$param
->coercion->_source_type_union->compiled_check;
my
$C
=
"Type::Coercion"
->new(
type_constraint
=>
$child
);
$C
->add_type_coercions(
$parent
=>
sub
{
my
$origref
=
@_
?
$_
[0] :
$_
;
my
@orig
=
@$origref
;
my
@new
;
for
my
$v
(
@orig
) {
return
$origref
unless
$coercible
->(
$v
);
push
@new
,
$param
->coerce(
$v
);
}
\
@new
;
},
);
return
$C
;
},
);
if
( __XS ) {
my
$xsub
= Type::Tiny::XS::get_coderef_for(
'ArrayLike'
);
my
$xsubname
= Type::Tiny::XS::get_subname_for(
'ArrayLike'
);
my
$inlined
=
$common
{inlined};
$cache
{ArrayLike} =
"Type::Tiny"
->new(
%common
,
compiled_type_constraint
=>
$xsub
,
inlined
=>
sub
{
(
$Type::Tiny::AvoidCallbacks
or not
$xsubname
)
?
goto
(
$inlined
)
:
qq/$xsubname($_[1])/
},
);
_reinstall_subs
$cache
{ArrayLike};
}
else
{
$cache
{ArrayLike} =
"Type::Tiny"
->new(
%common
);
}
@_
?
$cache
{ArrayLike}->parameterize( @{
$_
[0] } ) :
$cache
{ArrayLike};
}
if
( $] ge
'5.014'
) {
&Scalar::Util::set_prototype
(
$_
,
';$'
)
for
\
&HashLike
, \
&ArrayLike
;
}
sub
CodeLike () {
return
$cache
{CodeLike}
if
$cache
{CodeLike};
my
%common
= (
name
=>
"CodeLike"
,
constraint
=>
sub
{
ref
(
$_
) eq
q[CODE]
or blessed(
$_
) && _check_overload(
$_
,
q[&{}]
);
},
inlined
=>
sub
{
qq/ref($_[1]) eq q[CODE] or Scalar::Util::blessed($_[1]) && ${\ +_get_check_overload_sub() }($_[1], q[\&{}])/
;
},
type_default
=>
sub
{
return
sub
{} },
library
=> __PACKAGE__,
);
if
( __XS ) {
my
$xsub
= Type::Tiny::XS::get_coderef_for(
'CodeLike'
);
my
$xsubname
= Type::Tiny::XS::get_subname_for(
'CodeLike'
);
my
$inlined
=
$common
{inlined};
$cache
{CodeLike} =
"Type::Tiny"
->new(
%common
,
compiled_type_constraint
=>
$xsub
,
inlined
=>
sub
{
(
$Type::Tiny::AvoidCallbacks
or not
$xsubname
)
?
goto
(
$inlined
)
:
qq/$xsubname($_[1])/
},
);
_reinstall_subs
$cache
{CodeLike};
}
else
{
$cache
{CodeLike} =
"Type::Tiny"
->new(
%common
);
}
}
sub
BoolLike () {
return
$cache
{BoolLike}
if
$cache
{BoolLike};
$cache
{BoolLike} =
"Type::Tiny"
->new(
name
=>
"BoolLike"
,
constraint
=>
sub
{
!
defined
(
$_
)
or !
ref
(
$_
) && (
$_
eq
''
||
$_
eq
'0'
||
$_
eq
'1'
)
or blessed(
$_
) && (
_check_overload(
$_
,
q[bool]
)
or _check_overload(
$_
,
q[0+]
) &&
do
{
my
$n
=
sprintf
(
'%d'
,
$_
);
$n
==0 or
$n
==1 }
or
do
{
my
$d
=
$_
->can(
'DOES'
) ||
$_
->can(
'isa'
);
$_
->
$d
(
'boolean'
) }
)
},
inlined
=>
sub
{
qq/do {
local \$_ = $_;
!defined()
or !ref() && ( \$_ eq '' || \$_ eq '0' || \$_ eq '1' )
or Scalar::Util::blessed(\$_) && (
${\ +_get_check_overload_sub() }(\$_, q[bool])
or ${\ +_get_check_overload_sub() }(\$_, q[0+]) && do { my \$n = sprintf('%d', $_); \$n==0 or \$n==1 }
or do { my \$d = \$_->can('DOES') || \$_->can('isa'); \$_->\$d('boolean') }
)
}/
;
},
type_default
=>
sub
{
return
!!0 },
library
=> __PACKAGE__,
);
}
sub
TypeTiny () {
return
$cache
{TypeTiny}
if
defined
$cache
{TypeTiny};
$cache
{TypeTiny} =
"Type::Tiny"
->new(
name
=>
"TypeTiny"
,
constraint
=>
sub
{ blessed(
$_
) &&
$_
->isa(
q[Type::Tiny]
) },
inlined
=>
sub
{
my
$var
=
$_
[1];
"Scalar::Util::blessed($var) && $var\->isa(q[Type::Tiny])"
;
},
type_default
=>
sub
{
require
Types::Standard;
return
Types::Standard::Any() },
library
=> __PACKAGE__,
_build_coercion
=>
sub
{
my
$c
=
shift
;
$c
->add_type_coercions( _ForeignTypeConstraint(), \
&to_TypeTiny
);
$c
->freeze;
},
);
}
sub
_ForeignTypeConstraint () {
return
$cache
{_ForeignTypeConstraint}
if
defined
$cache
{_ForeignTypeConstraint};
$cache
{_ForeignTypeConstraint} =
"Type::Tiny"
->new(
name
=>
"_ForeignTypeConstraint"
,
constraint
=> \
&_is_ForeignTypeConstraint
,
inlined
=>
sub
{
qq/ref($_[1]) && do { require Types::TypeTiny; Types::TypeTiny::_is_ForeignTypeConstraint($_[1]) }/
;
},
library
=> __PACKAGE__,
);
}
my
%ttt_cache
;
sub
_is_ForeignTypeConstraint {
my
$t
=
@_
?
$_
[0] :
$_
;
return
!!1
if
ref
$t
eq
'CODE'
;
if
(
my
$class
= blessed
$t
) {
return
!!0
if
$class
->isa(
"Type::Tiny"
);
return
!!1
if
$class
->isa(
"Moose::Meta::TypeConstraint"
);
return
!!1
if
$class
->isa(
"MooseX::Types::TypeDecorator"
);
return
!!1
if
$class
->isa(
"Validation::Class::Simple"
);
return
!!1
if
$class
->isa(
"Validation::Class"
);
return
!!1
if
$t
->can(
"check"
);
}
!!0;
}
sub
to_TypeTiny {
my
$t
=
@_
?
$_
[0] :
$_
;
return
$t
unless
(
my
$ref
=
ref
$t
);
return
$t
if
$ref
=~ /^Type::Tiny\b/;
return
$ttt_cache
{ refaddr(
$t
) }
if
$ttt_cache
{ refaddr(
$t
) };
if
(
my
$class
= blessed
$t
) {
return
$t
if
$class
->isa(
"Type::Tiny"
);
return
_TypeTinyFromMoose(
$t
)
if
$class
eq
"MooseX::Types::TypeDecorator"
;
return
_TypeTinyFromMoose(
$t
)
if
$class
->isa(
"Moose::Meta::TypeConstraint"
);
return
_TypeTinyFromMoose(
$t
)
if
$class
->isa(
"MooseX::Types::TypeDecorator"
);
return
_TypeTinyFromMouse(
$t
)
if
$class
->isa(
"Mouse::Meta::TypeConstraint"
);
return
_TypeTinyFromValidationClass(
$t
)
if
$class
->isa(
"Validation::Class::Simple"
);
return
_TypeTinyFromValidationClass(
$t
)
if
$class
->isa(
"Validation::Class"
);
return
$t
->to_TypeTiny
if
$t
->can(
"DOES"
) &&
$t
->DOES(
"Type::Library::Compiler::TypeConstraint"
) &&
$t
->can(
"to_TypeTiny"
);
return
_TypeTinyFromGeneric(
$t
)
if
$t
->can(
"check"
);
}
return
_TypeTinyFromCodeRef(
$t
)
if
$ref
eq
q(CODE)
;
$t
;
}
sub
_TypeTinyFromMoose {
my
$t
=
$_
[0];
if
(
ref
$t
->{
"Types::TypeTiny::to_TypeTiny"
} ) {
return
$t
->{
"Types::TypeTiny::to_TypeTiny"
};
}
if
(
$t
->name ne
'__ANON__'
) {
my
$ts
=
'Types::Standard'
->get_type(
$t
->name );
return
$ts
if
$ts
->{_is_core};
}
my
(
$tt_class
,
$tt_opts
) =
$t
->can(
'parameterize'
) ? _TypeTinyFromMoose_parameterizable(
$t
) :
$t
->isa(
'Moose::Meta::TypeConstraint::Enum'
) ? _TypeTinyFromMoose_enum(
$t
) :
$t
->isa(
'Moose::Meta::TypeConstraint::Class'
) ? _TypeTinyFromMoose_class(
$t
) :
$t
->isa(
'Moose::Meta::TypeConstraint::Role'
) ? _TypeTinyFromMoose_role(
$t
) :
$t
->isa(
'Moose::Meta::TypeConstraint::Union'
) ? _TypeTinyFromMoose_union(
$t
) :
$t
->isa(
'Moose::Meta::TypeConstraint::DuckType'
) ? _TypeTinyFromMoose_ducktype(
$t
) :
_TypeTinyFromMoose_baseclass(
$t
);
$tt_opts
->{moose_type} =
$t
;
$tt_opts
->{display_name} =
$t
->name;
$tt_opts
->{message} =
sub
{
$t
->get_message(
$_
) }
if
$t
->has_message;
my
$new
=
$tt_class
->new(
%$tt_opts
);
$ttt_cache
{ refaddr(
$t
) } =
$new
;
weaken(
$ttt_cache
{ refaddr(
$t
) } );
$new
->{coercion} =
do
{
'Type::Coercion::FromMoose'
->new(
type_constraint
=>
$new
,
moose_coercion
=>
$t
->coercion,
);
}
if
$t
->has_coercion;
return
$new
;
}
sub
_TypeTinyFromMoose_baseclass {
my
$t
=
shift
;
my
%opts
;
$opts
{parent} = to_TypeTiny(
$t
->parent )
if
$t
->has_parent;
$opts
{constraint} =
$t
->constraint;
$opts
{inlined} =
sub
{
shift
;
$t
->_inline_check(
@_
) }
if
$t
->can(
"can_be_inlined"
) &&
$t
->can_be_inlined;
if
(
$opts
{inlined} ) {
my
%env
= %{
$t
->inline_environment || {} };
delete
(
$opts
{inlined} )
if
keys
%env
;
}
return
'Type::Tiny'
=> \
%opts
;
}
sub
_TypeTinyFromMoose_union {
my
$t
=
shift
;
my
@mapped
=
map
_TypeTinyFromMoose(
$_
), @{
$t
->type_constraints };
return
'Type::Tiny::Union'
=> {
type_constraints
=> \
@mapped
};
}
sub
_TypeTinyFromMoose_enum {
my
$t
=
shift
;
return
'Type::Tiny::Enum'
=> {
values
=> [ @{
$t
->
values
} ] };
}
sub
_TypeTinyFromMoose_class {
my
$t
=
shift
;
return
'Type::Tiny::Class'
=> {
class
=>
$t
->class };
}
sub
_TypeTinyFromMoose_role {
my
$t
=
shift
;
return
'Type::Tiny::Role'
=> {
role
=>
$t
->role };
}
sub
_TypeTinyFromMoose_ducktype {
my
$t
=
shift
;
return
'Type::Tiny::Duck'
=> {
methods
=> [ @{
$t
->methods } ] };
}
sub
_TypeTinyFromMoose_parameterizable {
my
$t
=
shift
;
my
(
$class
,
$opts
) = _TypeTinyFromMoose_baseclass(
$t
);
$opts
->{constraint_generator} =
sub
{
my
@args
=
map
{ is_TypeTiny(
$_
) ?
$_
->moose_type :
$_
}
@_
;
_TypeTinyFromMoose(
$t
->parameterize(
@args
) );
};
return
(
$class
,
$opts
);
}
sub
_TypeTinyFromValidationClass {
my
$t
=
$_
[0];
my
%opts
= (
parent
=> Types::Standard::HashRef(),
_validation_class
=>
$t
,
);
if
(
$t
->VERSION >=
"7.900048"
) {
$opts
{constraint} =
sub
{
$t
->params->clear;
$t
->params->add(
%$_
);
my
$f
=
$t
->filtering;
$t
->filtering(
'off'
);
my
$r
=
eval
{
$t
->validate };
$t
->filtering(
$f
||
'pre'
);
return
$r
;
};
$opts
{message} =
sub
{
$t
->params->clear;
$t
->params->add(
%$_
);
my
$f
=
$t
->filtering;
$t
->filtering(
'off'
);
my
$r
= (
eval
{
$t
->validate } ?
"OK"
:
$t
->errors_to_string );
$t
->filtering(
$f
||
'pre'
);
return
$r
;
};
}
else
{
$opts
{constraint} =
sub
{
$t
->params->clear;
$t
->params->add(
%$_
);
no
warnings
"redefine"
;
local
*Validation::Class::Directive::Filters::execute_filtering
=
sub
{
$_
[0] };
eval
{
$t
->validate };
};
$opts
{message} =
sub
{
$t
->params->clear;
$t
->params->add(
%$_
);
no
warnings
"redefine"
;
local
*Validation::Class::Directive::Filters::execute_filtering
=
sub
{
$_
[0] };
eval
{
$t
->validate } ?
"OK"
:
$t
->errors_to_string;
};
}
my
$new
=
"Type::Tiny"
->new(
%opts
);
$new
->coercion->add_type_coercions(
Types::Standard::HashRef() =>
sub
{
my
%params
=
%$_
;
for
my
$k
(
keys
%params
) {
delete
$params
{
$_
}
unless
$t
->get_fields(
$k
) }
$t
->params->clear;
$t
->params->add(
%params
);
eval
{
$t
->validate };
$t
->get_hash;
},
);
$ttt_cache
{ refaddr(
$t
) } =
$new
;
weaken(
$ttt_cache
{ refaddr(
$t
) } );
return
$new
;
}
sub
_TypeTinyFromGeneric {
my
$t
=
$_
[0];
my
%opts
= (
constraint
=>
sub
{
$t
->check(
@_
?
@_
:
$_
) },
);
$opts
{message} =
sub
{
$t
->get_message(
@_
?
@_
:
$_
) }
if
$t
->can(
"get_message"
);
$opts
{display_name} =
$t
->name
if
$t
->can(
"name"
);
$opts
{coercion} =
sub
{
$t
->coerce(
@_
?
@_
:
$_
) }
if
$t
->can(
"has_coercion"
)
&&
$t
->has_coercion
&&
$t
->can(
"coerce"
);
if
(
$t
->can(
'can_be_inlined'
)
&&
$t
->can_be_inlined
&&
$t
->can(
'inline_check'
) )
{
$opts
{inlined} =
sub
{
$t
->inline_check(
$_
[1] ) };
}
my
$new
=
"Type::Tiny"
->new(
%opts
);
$ttt_cache
{ refaddr(
$t
) } =
$new
;
weaken(
$ttt_cache
{ refaddr(
$t
) } );
return
$new
;
}
sub
_TypeTinyFromMouse {
my
$t
=
$_
[0];
my
%opts
= (
constraint
=>
sub
{
$t
->check(
@_
?
@_
:
$_
) },
message
=>
sub
{
$t
->get_message(
@_
?
@_
:
$_
) },
);
$opts
{display_name} =
$t
->name
if
$t
->can(
"name"
);
$opts
{coercion} =
sub
{
$t
->coerce(
@_
?
@_
:
$_
) }
if
$t
->can(
"has_coercion"
)
&&
$t
->has_coercion
&&
$t
->can(
"coerce"
);
if
(
$t
->{
'constraint_generator'
} ) {
$opts
{constraint_generator} =
sub
{
my
@args
=
map
{ is_TypeTiny(
$_
) ?
$_
->mouse_type :
$_
}
@_
;
_TypeTinyFromMouse(
$t
->parameterize(
@args
) );
};
}
my
$new
=
"Type::Tiny"
->new(
%opts
);
$ttt_cache
{ refaddr(
$t
) } =
$new
;
weaken(
$ttt_cache
{ refaddr(
$t
) } );
return
$new
;
}
my
$QFS
;
sub
_TypeTinyFromCodeRef {
my
$t
=
$_
[0];
my
%opts
= (
constraint
=>
sub
{
return
!!
eval
{
$t
->(
$_
) };
},
message
=>
sub
{
local
$@;
eval
{
$t
->(
$_
); 1 } or
do
{
chomp
$@;
return
$@
if
$@ };
return
sprintf
(
'%s did not pass type constraint'
, Type::Tiny::_dd(
$_
) );
},
);
if
(
$QFS
||=
"Sub::Quote"
->can(
"quoted_from_sub"
) ) {
my
(
undef
,
$perlstring
,
$captures
) = @{
$QFS
->(
$t
) || [] };
if
(
$perlstring
) {
$perlstring
=
"!!eval{ $perlstring }"
;
$opts
{inlined} =
sub
{
my
$var
=
$_
[1];
Sub::Quote::inlinify(
$perlstring
,
$var
,
$var
eq
q($_)
?
''
:
"local \$_ = $var;"
,
1,
);
}
if
$perlstring
&& !
$captures
;
}
}
my
$new
=
"Type::Tiny"
->new(
%opts
);
$ttt_cache
{ refaddr(
$t
) } =
$new
;
weaken(
$ttt_cache
{ refaddr(
$t
) } );
return
$new
;
}
1;