Validate: Rename "scalar" to "accept_scalar" and add "accept_array"
This commit is contained in:
parent
f8fe53cba9
commit
3382deba9a
2 changed files with 33 additions and 10 deletions
|
|
@ -13,7 +13,8 @@ my %builtin = map +($_,1), qw/
|
|||
default
|
||||
onerror
|
||||
trim
|
||||
elems scalar sort unique
|
||||
elems sort unique
|
||||
accept_scalar accept_array
|
||||
keys values unknown missing
|
||||
func
|
||||
/;
|
||||
|
|
@ -22,8 +23,9 @@ my %type_vals = map +($_,1), qw/scalar hash array any/;
|
|||
my %unknown_vals = map +($_,1), qw/remove reject pass/;
|
||||
my %missing_vals = map +($_,1), qw/create reject ignore/;
|
||||
my %implied_type = qw/
|
||||
accept_array scalar
|
||||
keys hash values hash unknown hash
|
||||
elems array sort array unique array scalar array
|
||||
elems array sort array unique array accept_scalar array
|
||||
/;
|
||||
my %sort_vals = (
|
||||
str => sub($x,$y) { $x cmp $y },
|
||||
|
|
@ -151,6 +153,7 @@ sub _compile($schema, $custom, $rec, $top, $validations=$top->{validations}) {
|
|||
if ($builtin{$name}) {
|
||||
confess "Invalid value for 'missing': $val" if $name eq 'missing' && !$missing_vals{$val};
|
||||
confess "Invalid value for 'unknown': $val" if $name eq 'unknown' && !$unknown_vals{$val};
|
||||
confess "Invalid value for 'accept_array': $val" if $name eq 'accept_array' && $val && $val ne 'first' && $val ne 'last';
|
||||
$val = $sort_vals{$val} || confess "Unknown value for 'sort': $val" if $name eq 'sort' && ref $val ne 'CODE';
|
||||
$top->{$name} = $val;
|
||||
next;
|
||||
|
|
@ -273,6 +276,10 @@ sub _validate_input {
|
|||
|
||||
my $type = $c->{type} // 'scalar';
|
||||
|
||||
# accept_array (needs to be done before 'trim')
|
||||
$_[1] = $_[1]->@* == 0 ? undef : $c->{accept_array} eq 'first' ? $_[1][0] : $_[1][ $#{$_[1]} ]
|
||||
if $c->{accept_array} && ref $_[1] eq 'ARRAY';
|
||||
|
||||
# trim (needs to be done before the 'default' test)
|
||||
$_[1] = trim $_[1] =~ s/\r//rg if defined $_[1] && !ref $_[1] && $type eq 'scalar' && (!exists $c->{trim} || $c->{trim});
|
||||
|
||||
|
|
@ -305,8 +312,8 @@ sub _validate_input {
|
|||
}
|
||||
|
||||
} elsif ($type eq 'array') {
|
||||
$_[1] = [$_[1]] if $c->{scalar} && !ref $_[1];
|
||||
return { validation => 'type', expected => $c->{scalar} ? 'array or scalar' : 'array', got => lc ref $_[1] || 'scalar' } if ref $_[1] ne 'ARRAY';
|
||||
$_[1] = [$_[1]] if $c->{accept_scalar} && !ref $_[1];
|
||||
return { validation => 'type', expected => $c->{accept_scalar} ? 'array or scalar' : 'array', got => lc ref $_[1] || 'scalar' } if ref $_[1] ne 'ARRAY';
|
||||
$_[1] = [$_[1]->@*]; # Create a shallow copy to prevent in-place modification.
|
||||
|
||||
} elsif ($type eq 'any') {
|
||||
|
|
@ -600,10 +607,10 @@ Failure is reported in a similar fashion to I<keys>:
|
|||
]
|
||||
}
|
||||
|
||||
=item scalar => 0/1
|
||||
=item accept_scalar => 0/1
|
||||
|
||||
Implies C<< type => 'array' >>, this option will also permit the input to be a
|
||||
scalar. In this case, the input is interpreted and returned as an array with
|
||||
scalar. In that case, the input is interpreted and returned as an array with
|
||||
only one element. This option exists to make it easy to validate multi-value
|
||||
form inputs. For example, consider C<query_decode()> in L<FU::Util>: a
|
||||
parameter in a query string is decoded into an array if it is listed multiple
|
||||
|
|
@ -613,16 +620,24 @@ times, a scalar if it only occcurs once. So we could either end up with:
|
|||
# OR:
|
||||
{ a => [1, 3], b => 1 }
|
||||
|
||||
With the I<scalar> option, we can accept both forms for C<a> and normalize into
|
||||
an array. The following schema definition can validate the above examples:
|
||||
With the I<accept_scalar> option, we can accept both forms for C<a> and
|
||||
normalize into an array. The following schema definition can validate the above
|
||||
examples:
|
||||
|
||||
{ type => 'hash',
|
||||
keys => {
|
||||
a => { type => 'array', scalar => 1 },
|
||||
a => { type => 'array', accept_scalar => 1 },
|
||||
b => { }
|
||||
}
|
||||
}
|
||||
|
||||
=item accept_array => false/'first'/'last'
|
||||
|
||||
Implies C<< type => 'scalar' >>. Similar to I<accept_scalar> but normalizes in
|
||||
the other direction: when the input is an array, only the first or last item is
|
||||
extracted and the other elements are ignored. If the input is an empty array,
|
||||
the value is taken to be C<undef>.
|
||||
|
||||
=item sort => $option
|
||||
|
||||
Implies C<< type => 'array' >>, sort the array after validating its elements.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue