Open zigorou opened 11 years ago
This is a code I'm using to put defaults on the schema based on a provide instance of this schema:
sub walkSchemaAndInstance {
my ($schema, $schemaPart, $instancePart) = @_;
if ( ref $instancePart eq 'HASH' ) {
foreach my $key (keys %{$instancePart}) {
if (not exists $schemaPart->{$key}) {
die "Instance does not mathch schema at key [$key] while trying to assign defaults"
} else {
if (exists $schemaPart->{$key}{'$'.'ref'}) {
my $ref = $schemaPart->{$key}{'$'.'ref'};
$ref =~ s/^#\///;
my $definition = $schema;
foreach my $refKey (split('/', $ref)) {
$definition = $definition->{$refKey};
}
$schemaPart->{$key} = dclone $definition;
}
if ($schemaPart->{$key}{type} eq 'object' and exists $schemaPart->{$key}{enum}) {
$schemaPart->{$key}{default} = $instancePart->{$key};
} elsif ($schemaPart->{$key}{type} eq 'object' and exists $schemaPart->{$key}{properties}) {
walkSchemaAndInstance($schemaPart->{$key}{properties}, $instancePart->{$key});
} else {
walkSchemaAndInstance($schemaPart->{$key}, $instancePart->{$key});
}
};
}
} elsif ( ref $instancePart eq 'ARRAY' ) {
die "Deafault values on complex array types are not supported yet" unless ($schemaPart->{items}{type} ne 'object' || exists $schemaPart->{items}{enum});
$schemaPart->{default} = $instancePart;
} else {
die unless (ref $schemaPart eq 'HASH' and $schemaPart->{type} ne 'object');
$schemaPart->{default} = $instancePart;
}
}
sub getSchemaWithDefaults {
my ($validator, $schema, $instance) = @_;
die "Supplied default values do not comply with specified schema" unless ( $validator->validate(dclone $schema, dclone $instance) );
my $schemaFused = dclone $schema;
walkSchemaAndInstance($schema, $schemaFused->{properties}, $instance);
return $schemaFused;
}
This would be a real nice addition.