Validate: drop creation of default values for built-ins

To better support merging multiple validations, which'll come next.
Probably.
This commit is contained in:
Yorhel 2025-03-14 10:52:09 +01:00
parent f248a33c1c
commit cea691dd55

View file

@ -164,10 +164,6 @@ sub compile($pkg, $schema, $validations={}) {
return $schema if $schema isa __PACKAGE__;
my $c = _compile $schema, $validations, 64;
$c->{type} //= 'scalar';
$c->{missing} //= 'create';
$c->{trim} //= 1 if $c->{type} eq 'scalar';
$c->{unknown} //= 'remove' if $c->{type} eq 'hash';
$c->{known_keys} = { map +($_,1), $c->{known_keys}->@* } if $c->{known_keys};
delete $c->{default} if ref $c->{default} eq 'SCALAR' && ${$c->{default}} eq 'required';
@ -194,8 +190,8 @@ sub _validate_rec {
my @err;
for my ($k, $s) ($c->{keys}->%*) {
if (!exists $_[1]{$k}) {
next if $s->{missing} eq 'ignore';
return { validation => 'missing', key => $k } if $s->{missing} eq 'reject';
next if $s->{missing} && $s->{missing} eq 'ignore';
return { validation => 'missing', key => $k } if $s->{missing} && $s->{missing} eq 'reject';
$_[1]{$k} = ref $s->{default} eq 'CODE' ? $s->{default}->() : $s->{default} // undef;
next if exists $s->{default};
}
@ -243,7 +239,6 @@ sub _validate_rec {
sub _validate_array {
my $c = $_[0];
return if $c->{type} ne 'array';
$_[1] = [sort { $c->{sort}->($a, $b) } $_[1]->@* ] if $c->{sort};
@ -269,8 +264,10 @@ sub _validate_array {
sub _validate_input {
my $c = $_[0];
my $type = $c->{type} // 'scalar';
# trim (needs to be done before the 'default' test)
$_[1] = trim $_[1] =~ s/\r//rg if defined $_[1] && !ref $_[1] && $c->{type} eq 'scalar' && $c->{trim};
$_[1] = trim $_[1] =~ s/\r//rg if defined $_[1] && !ref $_[1] && $type eq 'scalar' && (!exists $c->{trim} || $c->{trim});
# default
if (!defined $_[1] || (!ref $_[1] && $_[1] eq '')) {
@ -281,18 +278,18 @@ sub _validate_input {
return { validation => 'required' };
}
if ($c->{type} eq 'scalar') {
if ($type eq 'scalar') {
return { validation => 'type', expected => 'scalar', got => lc ref $_[1] } if ref $_[1];
} elsif ($c->{type} eq 'hash') {
} elsif ($type eq 'hash') {
return { validation => 'type', expected => 'hash', got => lc ref $_[1] || 'scalar' } if ref $_[1] ne 'HASH';
# Each branch below makes a shallow copy of the hash, so that further
# validations can perform in-place modifications without affecting the
# input.
if ($c->{unknown} eq 'remove') {
if (!$c->{unknown} || $c->{unknown} eq 'remove') {
$_[1] = { map +($_, $_[1]{$_}), grep $c->{known_keys}{$_}, keys $_[1]->%* };
} elsif ($c->{unknown} eq 'reject') {
} elsif ($c->{unknown} && $c->{unknown} eq 'reject') {
my @err = grep !$c->{known_keys}{$_}, keys $_[1]->%*;
return { validation => 'unknown', keys => \@err, expected => [ sort keys %{$c->{known_keys}} ] } if @err;
$_[1] = { $_[1]->%* };
@ -300,19 +297,16 @@ sub _validate_input {
$_[1] = { $_[1]->%* };
}
} elsif ($c->{type} eq 'array') {
} 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]->@*]; # Create a shallow copy to prevent in-place modification.
} elsif ($c->{type} eq 'any') {
} elsif ($type eq 'any') {
# No need to do anything here.
} else {
confess "Unknown type '$c->{type}'"; # Already checked in compile(), but be extra safe
}
&_validate_rec || &_validate_array;
&_validate_rec || ($type eq 'array' && &_validate_array);
}