Data-Validation

 view release on metacpan or  search on metacpan

lib/Data/Validation/Constraints.pm  view on Meta::CPAN

package Data::Validation::Constraints;

use namespace::autoclean;
use charnames qw( :full );

use Data::Validation::Constants qw( EXCEPTION_CLASS FALSE HASH TRUE );
use Data::Validation::Utils     qw( ensure_class_loaded load_class throw );
use List::Util                  qw( any );
use Scalar::Util                qw( looks_like_number );
use Try::Tiny;
use Unexpected::Functions       qw( KnownType );
use Unexpected::Types           qw( Any ArrayRef Bool Int Object Str Undef );
use Moo;

# Public attributes
has 'allowed'        => is => 'ro',   iss => ArrayRef, builder => sub { [] };

has 'max_length'     => is => 'ro',   isa => Int;

has 'max_value'      => is => 'ro',   isa => Int;

has 'method'         => is => 'ro',   isa => Str, required => TRUE;

has 'min_length'     => is => 'ro',   isa => Int;

has 'min_value'      => is => 'ro',   isa => Int;

has 'pattern'        => is => 'ro',   isa => Str;

has 'required'       => is => 'ro',   isa => Bool, default => FALSE;

has 'type'           => is => 'ro',   isa => Str | Undef;

has 'type_libraries' => is => 'ro',   isa => ArrayRef[Str],
   builder           => sub { [ 'Unexpected::Types' ] };

has 'type_registry'  => is => 'lazy', isa => Object, builder => sub {
   my $self = shift; ensure_class_loaded 'Type::Registry';
   my $reg  = Type::Registry->for_me;

   $reg->add_types( $_ ) for (@{ $self->type_libraries });

   return $reg;
};

has 'value'          => is => 'ro',   isa => Any;

# Public methods
sub new_from_method {
   my ($class, $attr) = @_;

   $class->can( $attr->{method} ) and return $class->new( $attr );

   return (load_class $class, 'isValid', $attr->{method})->new( $attr );
}

sub validate {
   my ($self, $v) = @_; my $method = $self->method; return $self->$method( $v );
}

around 'validate' => sub {
   my ($orig, $self, $v) = @_;

   not defined $v and $self->required and return FALSE;

   not defined $v and not $self->required and $self->method ne 'isMandatory'
      and return TRUE;

   return $orig->( $self, $v );
};

# Builtin factory validation methods
sub isAllowed {
   my ($self, $v) = @_;

   return (any { $_ eq $v } @{ $self->allowed }) ? TRUE : FALSE;
}

sub isBetweenValues {
   my ($self, $v) = @_;

   defined $self->min_value and $v < $self->min_value and return FALSE;
   defined $self->max_value and $v > $self->max_value and return FALSE;
   return TRUE;
}

sub isEqualTo {
   my ($self, $v) = @_;

   $self->isValidNumber( $v ) and $self->isValidNumber( $self->value )
      and return $v == $self->value ? TRUE : FALSE;

   return $v eq $self->value ? TRUE : FALSE;
}



( run in 0.962 second using v1.01-cache-2.11-cpan-39bf76dae61 )