Validate: rename rmwhitespace to trim and use builtin::trim()

This commit is contained in:
Yorhel 2025-03-05 15:39:46 +01:00
parent cbebc3a21e
commit e4b6b77e1b
2 changed files with 25 additions and 30 deletions

View file

@ -2,7 +2,7 @@ package FU::Validate 0.2;
use v5.36;
use experimental 'builtin', 'for_list';
use builtin qw/true false blessed/;
use builtin qw/true false blessed trim/;
use Carp 'confess';
use FU::Util 'to_bool';
@ -12,7 +12,7 @@ my %builtin = map +($_,1), qw/
type
default
onerror
rmwhitespace
trim
values scalar sort unique
keys unknown missing
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}'";
}
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 %{ $t->{schema}{keys} } if $t->{schema}{keys};
@ -155,7 +155,7 @@ sub compile($pkg, $schema, $validations={}) {
$c->{schema}{type} //= 'scalar';
$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';
confess "Invalid value for 'type': $c->{schema}{type}" if !$type_vals{$c->{schema}{type}};
@ -262,12 +262,8 @@ sub _validate_array {
sub _validate_input {
my $c = $_[0];
# rmwhitespace (needs to be done before the 'default' test)
if (defined $_[1] && !ref $_[1] && $c->{schema}{type} eq 'scalar' && $c->{schema}{rmwhitespace}) {
$_[1] =~ s/\r//g;
$_[1] =~ s/^\s*//;
$_[1] =~ s/\s*$//;
}
# trim (needs to be done before the 'default' test)
$_[1] = trim $_[1] =~ s/\r//rg if defined $_[1] && !ref $_[1] && $c->{schema}{type} eq 'scalar' && $c->{schema}{trim};
# default
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<{}>
is actually equivalent to:
{ type => 'scalar',
rmwhitespace => 1,
default => \'required',
missing => 'create',
{ type => 'scalar',
trim => 1,
default => \'required',
missing => 'create',
}
=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
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
validations. So a string containing only whitespace is considered an empty
string and will be treated according to this I<default> option. As an
additional side effect, other validations will never get to validate undef or
an empty string, as these values are either rejected or substituted with a
default.
The empty check is performed after I<trim> and before any other validations. So
a string containing only whitespace is considered an empty string and will be
treated according to this I<default> option. As an additional side effect,
other validations will never get to validate undef or an empty string, as these
values are either rejected or substituted with a default.
=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
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
any other validations. Setting I<rmwhitespace> to a false value will disable
this behavior.
any other validations. Setting I<trim> to a false value will disable this
behavior.
=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
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
example, if the top-level schema sets C<< rmwhitespace => 0 >>, then all
validations used in that schema may get input with whitespace around it.
example, if the top-level schema sets C<< trim => 0 >>, then all validations
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.
If a custom validation does not specify a I<type> option (and no type is

View file

@ -15,7 +15,7 @@ my %validations = (
defaultsub1 => { default => sub { 2 } },
defaultsub2 => { default => sub { defined $_[0] } },
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' },
revnum => { type => 'array', sort => sub($x,$y) { $y <=> $x } },
uniquelength => { type => 'array', values => { type => 'array' }, unique => sub { scalar @{$_[0]} } },
@ -68,11 +68,11 @@ t { defaultsub2 => 1 }, undef, '';
t { defaultsub2 => 1 }, '', 1;
t { onerrorsub => 1 }, undef, 'FU::Validate::err';
# rmwhitespace
# trim
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' };
t { rmwhitespace => 0 }, ' ', ' ';
t { trim => 0 }, ' ', ' ';
# arrays
f {}, [], { validation => 'type', expected => 'scalar', got => 'array' };
@ -161,7 +161,7 @@ t { mybool => 1 }, undef, 0;
t { mybool => 1 }, '', 0;
t { collapsews => 1 }, " \t\n ", ' ';
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' };
t { person => 1, default => 1 }, undef, 1;
f { person => 1 }, { sex => 1 }, { validation => 'person', error => { validation => 'keys', errors => [{ key => 'name', validation => 'required' }] } };