Aion

 view release on metacpan or  search on metacpan

lib/Aion/Types.pm  view on Meta::CPAN

					where { ref $_ eq "HASH" }
					awhere { my $A = A; ref $_ eq "HASH" && all { $A->test } values %$_ };
					subtype "Dict[k => A, ...]", as &HashRef,
						where {
							my $count = 0; my $k;
							for my $A (ARGS) {
								$k = $A, next unless ref $A;
								if(exists $_->{$k}) {
									return "" if $A->exclude($_->{$k});
									$count++;
								} else {
									return "" if !exists $A->{is_option};
								}
							}
							$count == keys %$_
						};
					subtype "Map[K, V]", as &HashRef,
						where {
							my ($K, $V) = ARGS;
							while(my ($k, $v) = each %$_) {
								return "" unless $K->include($k) && $V->include($v);
							}
							return 1;
						};
				subtype "Object`[class]", as &Ref,
					where { blessed($_) ne "" }
					awhere { blessed($_) && $_->isa(A) };
					subtype "Me", as &Object,
						init_where { SELF->{as} = Object([caller(2)]) };
					subtype "Rat", as 'Math::BigRat';
				subtype "RegexpLike", as &Ref,
					where { reftype($_) eq "REGEXP" || !!overload::Method($_, 'qr') };
				subtype "CodeLike", as &Ref,
					where { reftype($_) eq "CODE" || !!overload::Method($_, '&{}') };
				subtype "ArrayLike`[A]", as &Ref,
					where { reftype($_) eq "ARRAY" || !!overload::Method($_, '@{}') }
					awhere { &ArrayLike->test && do { my $A = A; all { $A->test } @$_ }};
					subtype "Lim[from, to?]", as &ArrayLike,
						init_where { unshift @{&ARGS}, 0 if @{&ARGS} == 1; }
						where { A <= @$_ && @$_ <= B };
				subtype "HashLike`[A]", as &Ref,
					where { reftype($_) eq "HASH" || !!overload::Method($_, "%{}") }
					awhere { &HashLike->test && do { my $A = A; all { $A->test } values %$_ }};
						subtype "HasProp[p...]", as &HashLike,
							where { my $x = $_; all { exists $x->{$_} } ARGS };
						subtype "LimKeys[from, to?]", as &HashLike,
							init_where { unshift @{&ARGS}, 0 if @{&ARGS} == 1; }
							where { A <= scalar keys %$_ && scalar keys %$_ <= B };
		
			subtype "Like", as &Str | &Object;
				subtype "HasMethods[m...]", as &Like,
					where { my $x = $_; all { $x->can($_) } ARGS };
				subtype "Overload`[m...]", as &Like,
					where { !!overload::Overloaded($_) }
					awhere { my $x = $_; all { overload::Method($x, $_) } ARGS };
				subtype "InstanceOf[class...]", as &Like, where { my $x = $_; all { $x->isa($_) } ARGS };
				subtype "ConsumerOf[role...]", as &Like, where { my $x = $_; all { $x->DOES($_) } ARGS };
				subtype "StrLike", as &Like, where { !blessed($_) or !!overload::Method($_, '""') };
					subtype "Len[from, to?]", as &StrLike,
						init_where { unshift @{&ARGS}, 0 if @{&ARGS} == 1; }
						where { A <= length($_) && length($_) <= B };
	
				subtype "NumLike", as &Num | &Object & Overload(["0+"]);
					sub Opened($) { Aion::Type::Lim->from(ref $_[0] eq "ARRAY"? $_[0][0]: $_[0]) };
					subtype "Range[from, to]", as &NumLike,
						init_where {
							SELF->{args}[0] = A->inc if UNIVERSAL::isa(A, 'Aion::Type::Lim');
							SELF->{args}[1] = B->dec if UNIVERSAL::isa(B, 'Aion::Type::Lim');
						}
						where { A <= $_ && $_ <= B };
						subtype "Float", as Range([-(POSIX::FLT_MAX), POSIX::FLT_MAX]);
						subtype "Double", as Range([-(DBL_MAX), DBL_MAX]);
						subtype "Bytes[n]", as Range([]),
							init_where {
								my $_8bits = A < 8? 8: _8BITS;
								my $N = 1 << ($_8bits * A - 1);
								SELF->{as} = Range([-$N, $N-1]);
							};
						subtype "PositiveBytes[n]", as Range([]),
							init_where {
								my $_8bits = A < 8? 8: _8BITS;
								my $M = 1 << ($_8bits*A);
								SELF->{as} = Range([0, $M-1]);
							};

	coerce &Str => from &Undef => via { "" };
	coerce &Int => from &Num => via { int($_+($_ < 0? -.5: .5)) };
	coerce &Bool => from &Any => via { !!$_ };

	subtype 'Join[separator]', as &Str;
	coerce &Join, from &ArrayRef, via { join A, @$_ };

	subtype 'Split[separator]', as &ArrayRef;
	coerce &Split, from &Str, via { [split A, $_] };

	coerce &Rat => from &StrRat => via { Math::BigRat->new($_) };

	subtype "PositiveNum", as &Num & Range([0, 'Inf']);
	subtype "PositiveInt", as &Int & Range([0, 'Inf']);
	subtype "Nat", as &Int & Range([1, 'Inf']);

	my $_none = ~&Any;
	sub None() { $_none }
};

$_->keyfn(\&Aion::Type::typed_sorted_args_key) for Union[], Intersection[];
(Enum[])->keyfn(\&Aion::Type::sorted_args_key);

%Aion::Type::range_lbound = map { (Scalar::Util::refaddr $_->{coerce} => $_->{name} eq 'Range'? '-Inf': 0) } Range[], Lim[], LimKeys[], Len[];

1;

__END__

=encoding utf-8

=head1 NAME

Aion::Types - a library of standard validators and it is used to create new validators

=head1 SYNOPSIS

lib/Aion/Types.pm  view on Meta::CPAN

	0 ~~ Bool  # -> 1
	undef ~~ Bool # -> 1
	"" ~~ Bool # -> 1
	
	2 ~~ Bool  # -> ""
	[] ~~ Bool # -> ""

=head2 Enum[A...]

Enumeration.

	3 ~~ Enum[1,2,3];            # -> 1
	"cat" ~~ Enum["cat", "dog"]; # -> 1
	4 ~~ Enum[1,2,3];            # -> ""
	
	Enum["cat"] <= Enum["cat", "dog"] # -> 1
	Enum["cat", "dog"] <= Enum["cat", "dog"] # -> 1
	
	Enum(["cat", "dog"])->disjoint(Enum[1]) # -> 1
	Enum(["cat", "dog"])->disjoint(Enum["ret", "cat"]) # -> ""
	
	Enum[1,2] <= Enum[1,2,3]          # -> 1
	Enum[1,2] <= Enum[2,3]            # -> ""
	Enum[1,2] == Enum[2,1]            # -> 1
	Enum[1,2] < Enum[1,2,3]           # -> 1
	Enum[1,2,3] > Enum[1,2]           # -> 1
	Enum[1,2] == (Enum[1] | Enum[2])  # -> 1

=head2 Maybe[A]

C<undef> or type in C<[]>.

	undef ~~ Maybe[Int] # -> 1
	4 ~~ Maybe[Int]     # -> 1
	"" ~~ Maybe[Int]    # -> ""

=head2 Undef

Only C<undef>.

	undef ~~ Undef # -> 1
	0 ~~ Undef     # -> ""

=head2 Defined

Everything except C<undef>.

	\0 ~~ Defined    # -> 1
	undef ~~ Defined # -> ""

=head2 Value

Defined values without references.

	3 ~~ Value  # -> 1
	\3 ~~ Value    # -> ""
	undef ~~ Value # -> ""

=head2 Len[from?, to]

Specifies a length value from C<from> or 0 to C<to>.

	"1234" ~~ Len[3]   # -> ""
	"123" ~~ Len[3]    # -> 1
	"12" ~~ Len[3]     # -> 1
	"" ~~ Len[1, 2]    # -> ""
	"1" ~~ Len[1, 2]   # -> 1
	"12" ~~ Len[1, 2]  # -> 1
	"123" ~~ Len[1, 2] # -> ""
	
	Len[3] <= Len[3] # -> 1
	Len[3] <= Len[4] # -> 1
	Len[3] <= Len[2] # -> ""

=head2 Version

Perl version.

	1.1.0 ~~ Version   # -> 1
	1.1.0.5 ~~ Version # -> 1
	v1.1.0 ~~ Version  # -> 1
	v1.1 ~~ Version    # -> 1
	v1 ~~ Version      # -> 1
	1.1 ~~ Version     # -> ""
	"1.1.0" ~~ Version # -> ""

=head2 Str

Strings, including numbers.

	1.1 ~~ Str   # -> 1
	"" ~~ Str    # -> 1
	1.1.0 ~~ Str # -> ""

=head2 Uni

Unicode strings with the utf8 flag or if decoding to utf8 occurs without errors.

	"↭" ~~ Uni # -> 1
	123 ~~ Uni # -> ""
	do {no utf8; "↭" ~~ Uni} # -> 1

=head2 Bin

Binary strings without the utf8 flag and octets with numbers less than 128.

	123 ~~ Bin # -> 1
	"z" ~~ Bin # -> 1
	"↭" ~~ Bin # -> ""
	do {no utf8; "↭" ~~ Bin }   # -> ""

=head2 StartsWith[begin]

The line starts with C<begin>.

	"Hi, world!" ~~ StartsWith["Hi,"]; # -> 1
	"Hi world!" ~~ StartsWith["Hi,"];  # -> ""

=head2 EndsWith[end]

The line ends with C<end>.



( run in 0.909 second using v1.01-cache-2.11-cpan-aadc1410aed )