Validate: rename rmwhitespace to trim and use builtin::trim()
This commit is contained in:
parent
cbebc3a21e
commit
e4b6b77e1b
2 changed files with 25 additions and 30 deletions
|
|
@ -2,7 +2,7 @@ package FU::Validate 0.2;
|
||||||
|
|
||||||
use v5.36;
|
use v5.36;
|
||||||
use experimental 'builtin', 'for_list';
|
use experimental 'builtin', 'for_list';
|
||||||
use builtin qw/true false blessed/;
|
use builtin qw/true false blessed trim/;
|
||||||
use Carp 'confess';
|
use Carp 'confess';
|
||||||
use FU::Util 'to_bool';
|
use FU::Util 'to_bool';
|
||||||
|
|
||||||
|
|
@ -12,7 +12,7 @@ my %builtin = map +($_,1), qw/
|
||||||
type
|
type
|
||||||
default
|
default
|
||||||
onerror
|
onerror
|
||||||
rmwhitespace
|
trim
|
||||||
values scalar sort unique
|
values scalar sort unique
|
||||||
keys unknown missing
|
keys unknown missing
|
||||||
func
|
func
|
||||||
|
|
@ -130,7 +130,7 @@ sub _compile($schema, $validations, $rec) {
|
||||||
confess "Incompatible types, '$t->[0]' requires '$t->{schema}{type}', but another validation requires '$top{type}'";
|
confess "Incompatible types, '$t->[0]' requires '$t->{schema}{type}', but another validation requires '$top{type}'";
|
||||||
}
|
}
|
||||||
exists $t->{schema}{$_} and !exists $top{$_} and $top{$_} = delete $t->{schema}{$_}
|
exists $t->{schema}{$_} and !exists $top{$_} and $top{$_} = delete $t->{schema}{$_}
|
||||||
for qw/default onerror rmwhitespace type scalar unknown missing sort unique/;
|
for qw/default onerror trim type scalar unknown missing sort unique/;
|
||||||
|
|
||||||
push @keys, keys %{ delete $t->{known_keys} };
|
push @keys, keys %{ delete $t->{known_keys} };
|
||||||
push @keys, keys %{ $t->{schema}{keys} } if $t->{schema}{keys};
|
push @keys, keys %{ $t->{schema}{keys} } if $t->{schema}{keys};
|
||||||
|
|
@ -155,7 +155,7 @@ sub compile($pkg, $schema, $validations={}) {
|
||||||
|
|
||||||
$c->{schema}{type} //= 'scalar';
|
$c->{schema}{type} //= 'scalar';
|
||||||
$c->{schema}{missing} //= 'create';
|
$c->{schema}{missing} //= 'create';
|
||||||
$c->{schema}{rmwhitespace} //= 1 if $c->{schema}{type} eq 'scalar';
|
$c->{schema}{trim} //= 1 if $c->{schema}{type} eq 'scalar';
|
||||||
$c->{schema}{unknown} //= 'remove' if $c->{schema}{type} eq 'hash';
|
$c->{schema}{unknown} //= 'remove' if $c->{schema}{type} eq 'hash';
|
||||||
|
|
||||||
confess "Invalid value for 'type': $c->{schema}{type}" if !$type_vals{$c->{schema}{type}};
|
confess "Invalid value for 'type': $c->{schema}{type}" if !$type_vals{$c->{schema}{type}};
|
||||||
|
|
@ -262,12 +262,8 @@ sub _validate_array {
|
||||||
sub _validate_input {
|
sub _validate_input {
|
||||||
my $c = $_[0];
|
my $c = $_[0];
|
||||||
|
|
||||||
# rmwhitespace (needs to be done before the 'default' test)
|
# trim (needs to be done before the 'default' test)
|
||||||
if (defined $_[1] && !ref $_[1] && $c->{schema}{type} eq 'scalar' && $c->{schema}{rmwhitespace}) {
|
$_[1] = trim $_[1] =~ s/\r//rg if defined $_[1] && !ref $_[1] && $c->{schema}{type} eq 'scalar' && $c->{schema}{trim};
|
||||||
$_[1] =~ s/\r//g;
|
|
||||||
$_[1] =~ s/^\s*//;
|
|
||||||
$_[1] =~ s/\s*$//;
|
|
||||||
}
|
|
||||||
|
|
||||||
# default
|
# default
|
||||||
if (!defined $_[1] || (!ref $_[1] && $_[1] eq '')) {
|
if (!defined $_[1] || (!ref $_[1] && $_[1] eq '')) {
|
||||||
|
|
@ -410,10 +406,10 @@ validation to be performed. None of the options or validations are required,
|
||||||
but some built-ins have default values. This means that the empty schema C<{}>
|
but some built-ins have default values. This means that the empty schema C<{}>
|
||||||
is actually equivalent to:
|
is actually equivalent to:
|
||||||
|
|
||||||
{ type => 'scalar',
|
{ type => 'scalar',
|
||||||
rmwhitespace => 1,
|
trim => 1,
|
||||||
default => \'required',
|
default => \'required',
|
||||||
missing => 'create',
|
missing => 'create',
|
||||||
}
|
}
|
||||||
|
|
||||||
=head2 Built-in options
|
=head2 Built-in options
|
||||||
|
|
@ -444,12 +440,11 @@ C<$val> is returned instead. If C<$val> is a CODE reference, the subroutine is
|
||||||
called with the original value (which is either no argument, undef or an empty
|
called with the original value (which is either no argument, undef or an empty
|
||||||
string) and the return value of the subroutine is used as value instead.
|
string) and the return value of the subroutine is used as value instead.
|
||||||
|
|
||||||
The empty check is performed after I<rmwhitespace> and before any other
|
The empty check is performed after I<trim> and before any other validations. So
|
||||||
validations. So a string containing only whitespace is considered an empty
|
a string containing only whitespace is considered an empty string and will be
|
||||||
string and will be treated according to this I<default> option. As an
|
treated according to this I<default> option. As an additional side effect,
|
||||||
additional side effect, other validations will never get to validate undef or
|
other validations will never get to validate undef or an empty string, as these
|
||||||
an empty string, as these values are either rejected or substituted with a
|
values are either rejected or substituted with a default.
|
||||||
default.
|
|
||||||
|
|
||||||
=item onerror => $val
|
=item onerror => $val
|
||||||
|
|
||||||
|
|
@ -461,11 +456,11 @@ If C<$val> is a CODE reference, the subroutine is called with the (partially
|
||||||
normalized) input as first argument and error object as second argument. The
|
normalized) input as first argument and error object as second argument. The
|
||||||
return value of the subroutine is then returned for this validation.
|
return value of the subroutine is then returned for this validation.
|
||||||
|
|
||||||
=item rmwhitespace => 0/1
|
=item trim => 0/1
|
||||||
|
|
||||||
By default, any whitespace around scalar-type input is removed before testing
|
By default, any whitespace around scalar-type input is removed before testing
|
||||||
any other validations. Setting I<rmwhitespace> to a false value will disable
|
any other validations. Setting I<trim> to a false value will disable this
|
||||||
this behavior.
|
behavior.
|
||||||
|
|
||||||
=item keys => $hashref
|
=item keys => $hashref
|
||||||
|
|
||||||
|
|
@ -818,8 +813,8 @@ schema that contains the I<func> built-in option to do the actual validation.
|
||||||
Custom validations can also set built-in options, but the semantics differ a
|
Custom validations can also set built-in options, but the semantics differ a
|
||||||
little depending on the option. First, be aware that many of the built-in
|
little depending on the option. First, be aware that many of the built-in
|
||||||
options apply to the whole schema and not just to the custom validation. For
|
options apply to the whole schema and not just to the custom validation. For
|
||||||
example, if the top-level schema sets C<< rmwhitespace => 0 >>, then all
|
example, if the top-level schema sets C<< trim => 0 >>, then all validations
|
||||||
validations used in that schema may get input with whitespace around it.
|
used in that schema may get input with whitespace around it.
|
||||||
|
|
||||||
All validations used in a schema need to agree upon a single I<type> option.
|
All validations used in a schema need to agree upon a single I<type> option.
|
||||||
If a custom validation does not specify a I<type> option (and no type is
|
If a custom validation does not specify a I<type> option (and no type is
|
||||||
|
|
|
||||||
10
t/validate.t
10
t/validate.t
|
|
@ -15,7 +15,7 @@ my %validations = (
|
||||||
defaultsub1 => { default => sub { 2 } },
|
defaultsub1 => { default => sub { 2 } },
|
||||||
defaultsub2 => { default => sub { defined $_[0] } },
|
defaultsub2 => { default => sub { defined $_[0] } },
|
||||||
onerrorsub => { onerror => sub { ref $_[1] } },
|
onerrorsub => { onerror => sub { ref $_[1] } },
|
||||||
collapsews => { rmwhitespace => 0, func => sub { $_[0] =~ s/\s+/ /g; 1 } },
|
collapsews => { trim => 0, func => sub { $_[0] =~ s/\s+/ /g; 1 } },
|
||||||
neverfails => { onerror => 'err' },
|
neverfails => { onerror => 'err' },
|
||||||
revnum => { type => 'array', sort => sub($x,$y) { $y <=> $x } },
|
revnum => { type => 'array', sort => sub($x,$y) { $y <=> $x } },
|
||||||
uniquelength => { type => 'array', values => { type => 'array' }, unique => sub { scalar @{$_[0]} } },
|
uniquelength => { type => 'array', values => { type => 'array' }, unique => sub { scalar @{$_[0]} } },
|
||||||
|
|
@ -68,11 +68,11 @@ t { defaultsub2 => 1 }, undef, '';
|
||||||
t { defaultsub2 => 1 }, '', 1;
|
t { defaultsub2 => 1 }, '', 1;
|
||||||
t { onerrorsub => 1 }, undef, 'FU::Validate::err';
|
t { onerrorsub => 1 }, undef, 'FU::Validate::err';
|
||||||
|
|
||||||
# rmwhitespace
|
# trim
|
||||||
t {}, " Va\rl id \n ", 'Val id';
|
t {}, " Va\rl id \n ", 'Val id';
|
||||||
t { rmwhitespace => 0 }, " Va\rl id \n ", " Va\rl id \n ";
|
t { trim => 0 }, " Va\rl id \n ", " Va\rl id \n ";
|
||||||
f {}, ' ', { validation => 'required' };
|
f {}, ' ', { validation => 'required' };
|
||||||
t { rmwhitespace => 0 }, ' ', ' ';
|
t { trim => 0 }, ' ', ' ';
|
||||||
|
|
||||||
# arrays
|
# arrays
|
||||||
f {}, [], { validation => 'type', expected => 'scalar', got => 'array' };
|
f {}, [], { validation => 'type', expected => 'scalar', got => 'array' };
|
||||||
|
|
@ -161,7 +161,7 @@ t { mybool => 1 }, undef, 0;
|
||||||
t { mybool => 1 }, '', 0;
|
t { mybool => 1 }, '', 0;
|
||||||
t { collapsews => 1 }, " \t\n ", ' ';
|
t { collapsews => 1 }, " \t\n ", ' ';
|
||||||
t { collapsews => 1 }, ' x ', ' x ';
|
t { collapsews => 1 }, ' x ', ' x ';
|
||||||
t { collapsews => 1, rmwhitespace => 1 }, ' x ', 'x';
|
t { collapsews => 1, trim => 1 }, ' x ', 'x';
|
||||||
f { person => 1 }, 1, { validation => 'type', expected => 'hash', got => 'scalar' };
|
f { person => 1 }, 1, { validation => 'type', expected => 'hash', got => 'scalar' };
|
||||||
t { person => 1, default => 1 }, undef, 1;
|
t { person => 1, default => 1 }, undef, 1;
|
||||||
f { person => 1 }, { sex => 1 }, { validation => 'person', error => { validation => 'keys', errors => [{ key => 'name', validation => 'required' }] } };
|
f { person => 1 }, { sex => 1 }, { validation => 'person', error => { validation => 'keys', errors => [{ key => 'name', validation => 'required' }] } };
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue