Aion
view release on metacpan or search on metacpan
lib/Aion/Type.pm view on Meta::CPAN
name => "Range",
args => [3, 5],
init => [sub {
@{$Aion::Type::SELF}{qw/min max/} = @{$Aion::Type::SELF->{args}};
}],
test => sub { $Aion::Type::SELF->{min} <= $_ && $_ <= $Aion::Type::SELF->{max} },
);
$Range->init;
3 ~~ $Range # -> 1
4 ~~ $Range # -> 1
5 ~~ $Range # -> 1
2 ~~ $Range # -> ""
6 ~~ $Range # -> ""
=head2 include ($element)
Checks whether the argument belongs to the class.
my $PositiveInt = Aion::Type->new(
name => "PositiveInt",
test => sub { /^\d+$/ },
);
$PositiveInt->include(5) # -> 1
$PositiveInt->include(-6) # -> ""
=head2 exclude ($element)
Checks that the argument does not belong to the class.
my $PositiveInt = Aion::Type->new(
name => "PositiveInt",
test => sub { /^\d+$/ },
);
$PositiveInt->exclude(5) # -> ""
$PositiveInt->exclude(-6) # -> 1
=head2 coerce ($value)
Cast C<$value> to type if the cast from type and function is in C<< $self-E<gt>{coerce} >>.
Corresponds to the C<< E<gt>E<gt> >> operator.
my $Int = Aion::Type->new(name => "Int", test => sub { /^-?\d+\z/ });
my $Num = Aion::Type->new(name => "Num", test => sub { /^-?\d+(\.\d+)?\z/ });
my $Bool = Aion::Type->new(name => "Bool", test => sub { /^(1|0|)\z/ });
push @{$Int->{coerce}}, [$Bool, sub { 0+$_ }];
push @{$Int->{coerce}}, [$Num, sub { int($_+.5) }];
$Int->coerce(5.5) # => 6
$Int->coerce(undef) # => 0
$Int->coerce("abc") # => abc
=head2 detail ($element, $feature)
Generates an error message.
my $Int = Aion::Type->new(name => "Int");
$Int->detail(-5, "Feature car") # => Feature car must have the type Int. The it is -5!
my $Num = Aion::Type->new(name => "Num", message => sub {
"Error: $_ is'nt $Aion::Type::SELF->{property}!"
});
$Num->detail("x", "car") # => Error: x is'nt car!
=head2 validate ($element, $feature)
Checks C<$element> and throws a C<detail> message if the element does not belong to the class.
my $PositiveInt = Aion::Type->new(
name => "PositiveInt",
test => sub { /^\d+$/ },
);
eval {
$PositiveInt->validate(-1, "Neg")
};
$@ # ~> Neg must have the type PositiveInt. The it is -1
=head2 val_to_str ($val)
Converts C<$val> to a string.
Aion::Type->new->val_to_str([1,2,{x=>6}]) # => [1, 2, {x => 6}]
=head2 instanceof ($type)
Determines that a type is a subtype of another C<$type> by type name.
Doesn't work in C<|> and C<~>. Doesn't check arguments.
my $Int = Aion::Type->new(name => "Int");
my $PositiveInt = Aion::Type->new(name => "PositiveInt", as => $Int);
$PositiveInt->instanceof('Int'); # -> 1
$PositiveInt->instanceof('PositiveInt'); # -> 1
$Int->instanceof('PositiveInt'); # -> ""
my $MyEnum = Aion::Type->new(name => "MyEnum", args => [3, 5, 'car']);
($MyEnum & $PositiveInt)->instanceof('Int'); # -> 1
=head2 is_set_theoretic
Checks that the type is set-theoretic (ie - the C<|>, C<&> or C<~> operator).
=head2 simplify
If the expression has no values, it will return C<~Any>, otherwise it will return the expression.
Simplification of the expression in this function may appear in the future.
package Aion::Types;
my $type = (Enum[1,2] | Enum[2,3]) & Enum[2,3,4];
lib/Aion/Type.pm view on Meta::CPAN
Reverse operation to C<identical>.
my $Int = Aion::Type->new(name => "Int");
my $PositiveInt = Aion::Type->new(name => "PositiveInt", as => $Int);
$Int->distinct($PositiveInt) # -> 1
$Int ne $PositiveInt # -> 1
=head2 disjoint ($other)
A type does not overlap with another type.
=head2 subset ($type)
Specifies that it is a subset of the specified type.
=head2 superset ($type)
Specifies that it is a superset of the specified type.
=head2 subproper ($other)
A type is a strict subset of another.
=head2 superproper ($other)
A type is a strict superset of another.
=head2 equals ($other)
A type is equivalent to another type.
=head2 differs ($other)
A type is not equivalent to another type.
=head2 disjoint ($other)
A type has no overlap with another type.
=head2 intersects ($other)
A type has an intersection or intersections with another type.
=head2 make ($pkg)
Creates a subroutine with no arguments that returns a type.
BEGIN {
Aion::Type->new(name=>"Rim", test => sub { /^[IVXLCDM]+$/i })->make(__PACKAGE__);
}
"IX" ~~ Rim # => 1
If C<init> is specified, then each time the subroutine is used, a type will be created and initialized.
eval { Aion::Type->new(name=>"Rim", init => sub {...})->make(__PACKAGE__) }; $@ # ~> init_where won't work in Rim
If the routine cannot be created, an exception is thrown.
eval { Aion::Type->new(name=>"Rim")->make }; $@ # ~> syntax error
=head2 make_arg ($pkg)
Creates a subroutine with arguments that returns a type.
BEGIN {
Aion::Type->new(name=>"Len", test => sub {
$Aion::Type::SELF->{args}[0] <= length($_) && length($_) <= $Aion::Type::SELF->{args}[1]
})->make_arg(__PACKAGE__, 1);
}
"IX" ~~ Len[2,2] # => 1
If the routine cannot be created, an exception is thrown.
eval { Aion::Type->new(name=>"Rim")->make_arg }; $@ # ~> syntax error
=head2 make_maybe_arg ($pkg)
Creates a subroutine with or without arguments.
BEGIN {
Aion::Type->new(
name => "Enum123",
test => sub { $_ ~~ [1,2,3] },
a_test => sub { $_ ~~ $Aion::Type::SELF->{args} },
)->make_maybe_arg(__PACKAGE__);
}
3 ~~ Enum123 # -> 1
3 ~~ Enum123[4,5,6] # -> ""
5 ~~ Enum123[4,5,6] # -> 1
If the routine cannot be created, an exception is thrown.
eval { Aion::Type->new(name=>"Rim")->make_maybe_arg }; $@ # ~> syntax error
=head2 args ()
List of arguments.
=head2 name ()
Type name.
=head2 as ()
Parent type.
=head2 message (;&message)
Message accessor. Uses C<&message> to generate an error message.
=head2 title (;$title)
Header accessor (used to create the B<swagger> schema).
=head2 description (;$description)
Description accessor (used to create a B<swagger> schema).
=head2 example (;$example)
Example accessor (used to create the B<swagger> schema).
=head2 true ()
Always returns C<1>. Needed to specify a test for a type without C<where>.
=head2 clone ()
Clone type.
my $type = Aion::Type->new(name => 'New');
my $type10 = $type->clone(args => [10]);
$type->stringify # => New
$type10->stringify # => New[10]
=head2 is_primitive ()
This is a primitive type, that is, one in whose hierarchy there are no set-theoretic operators.
Aion::Types::Int->is_primitive # -> 1
Aion::Types::Like->is_primitive # -> ""
=head2 is_union ()
This is a union of types.
Aion::Types::Int->is_union # -> ""
(Aion::Types::Int | Aion::Types::Int)->is_union # -> 1
=head2 is_intersection ()
This is the intersection of types.
Aion::Types::Int->is_intersection # -> ""
(Aion::Types::Int & Aion::Types::Int)->is_intersection # -> 1
=head2 is_exclude ()
This is a type exception.
Aion::Types::Any->is_exclude # -> ""
(~Aion::Types::Any)->is_exclude # -> 1
Aion::Types::None->is_exclude # -> 1
~Aion::Types::Any eq Aion::Types::None # -> 1
=head2 is_enum ()
This is an enumeration.
( run in 1.959 second using v1.01-cache-2.11-cpan-2e0ccfb7a10 )