Config-Validate

 view release on metacpan or  search on metacpan

lib/Config/Validate.pm  view on Meta::CPAN

  sub _init :Init {
    my ($self, $args) = @_;
    
    $types[$$self] = clone(\%types);

    unless (defined $have_data_path) {
      eval { require Data::Path; };
      $have_data_path = $@ eq '' ? 1 : 0;
    }

    if ($self->data_path and not $have_data_path) {
      _throw "Data::Path requested, but cannot find module";
    }

    return;
  }

  sub _parse_add_type_params {
    # TODO: This should be updated to allow 'byreference'
    my $spec = { name => { type => SCALAR },
                 validate => { type => CODEREF,
                               optional => 1,
                             },
                 init     => { type => CODEREF,
                               optional => 1,
                             },
                 finish   => { type => CODEREF,
                               optional => 1,
                             },
               };
    return validate_with(params         => \@_,
                         spec           => $spec,
                         stack_skip     => 2,
                         normalize_keys => sub {
                           return lc $_[0];
                         },
                        );
  }

  sub add_default_type {
    # this is a function, but if it's called as a method, that's
    # fine too.
    my $self;
    if (@_) {
      $self = shift if blessed $_[0];
      shift if $_[0] eq 'Config::Validate';
    }
      
    my %p = _parse_add_type_params(@_);    
    if ($self) {
      $self->add_type(%p);
    }

    if (defined $types{$p{name}}) {
      _throw "Attempted to add type '$p{name}' that already exists";
    }

    my $type = clone(\%p);
    delete $type->{name};
    if (keys %$type == 0) {
      _throw "No callbacks defined for type '$p{name}'";
    }
    $types{$p{name}} = $type;
    

    return;
  }

  sub add_type {
    my $self = shift;
    my %p = _parse_add_type_params(@_);
    
    if (defined $types[$$self]{$p{name}}) {
      _throw "Attempted to add type '$p{name}' that already exists";
    }
    
    my $type = clone(\%p);
    delete $type->{name};
    if (keys %$type == 0) {
      _throw "No callbacks defined for type '$p{name}'";
    }
    $types[$$self]{$p{name}} = $type;
    return;
  }

  sub reset_default_types {
    %types = %default_types;
    return;
  }

  sub _type_callback {
    my ($self, $callback, @args) = @_;

    while (my ($name, $value) = each %{ $types[$$self] }) {
      if (defined $value->{$callback}) {
        $value->{$callback}(@args);
      }
    }
    return;
  }  

  # Unfortunately, the validate function/method used to not use
  # Params::Validate, and used to instead be callable as a one
  # argument version as an instance method, or a two argument version
  # (schema and config) as a function.  This functin is to detect
  # which way it is being called, and normalize the argument list.
  sub _parse_validate_args {
    my (@args) = @_;

    if (@args < 2) {
      _throw "Config::Validate::validate requires at least two arguments";
    }

    my $self;
    if (blessed $args[0]) {
      # called as a method
      $self = shift @args;
      if (@args == 1) {
        @args = (schema => $schema[$$self], 
                 config => $args[0]);
      } else {
        push(@args, schema => $self->schema);
      }
    } else {
      $self = Config::Validate->new();
      if (@args == 2) {
        @args = (config => $args[0],
                 schema => $args[1]);
      }
    }

    my $spec = { schema => { type => HASHREF },
                 config => { type => HASHREF },
               };
    my %args = validate_with(params         => \@args,
                             spec           => $spec,
                             stack_skip     => 2,
                             normalize_keys => sub { 
                               return lc $_[0];
                             },

lib/Config/Validate.pm  view on Meta::CPAN

message describing the problem.

There was formerly a one and two argument variant of this sub.  It is
still supported, but deprecated.

=head2 add_type

The C<add_type> method allows you to register a validation type on
just a single instance of C<Config::Validate>.  The parameters are as
follows: 

=over 8

=item * name

This is the name to be specified in the schema to use this validation
type.  This is a mandatory parameter.

=item * validate

The value of C<validate> should be a callback that will be run when it
is necessary to validate a field of this type.  The callback will be
passed the C<Config::Validate> object, the name of the field being
validated, the schema definition of that field, and an array reference
containing the path into the data structure.  You can use the
C<mkpath> method to convert the path to a more readable form for error
messages and such.

=item * init

The value of C<init> should be a callback that will be run before any
validation is done.  The callback will be passed the
C<Config::Validate> object, the schema, and the configuration being
validated.

=item * finish

The value of C<finish> should be a callback that will be run after any
validation is done.  The callback will be passed the
C<Config::Validate> object, the schema, and the configuration being
validated.

=back

=head2 add_default_type

The C<add_default_type> method allows you to register a validation
type for all new C<Config::Validate> instances.  It can be called as a
function, class method, or instance method.  If it is called as an
instance method, then the new type will also be added to that
instance.  The parameters are the same as C<add_type>.

=head2 reset_default_types

The C<reset_default_types> method removes all user defined types from
the base class.  Any instances that are alread created will retain
their existing type configuration.

=head2 mkpath

This is a convenience function for people writing callbacks and user
defined type validation.  It takes either an array or array reference
and returns a string that represents the path to a specific item in
the configuration.  This might be useful if you're interested in
having your error messages be consistent with the rest of
C<Config::Validate>.  This is available for export, but not exported
by default.  Note: this is a function, not a method.

=head1 AUTHOR

Clayton O'Neill

Eval for e-mail address: C<join('@', join('.', qw(cv 20 coneill)), 'xoxy.net')>

=head1 LICENSE AND COPYRIGHT

Copyright (C) 2007-2008 by Clayton O'Neill

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.8.5 or,
at your option, any later version of Perl 5 you may have available.


=cut



( run in 2.816 seconds using v1.01-cache-2.11-cpan-140bd7fdf52 )