App-CSVUtils
view release on metacpan or search on metacpan
lib/App/CSVUtils/csv_check_cell_values.pm view on Meta::CPAN
_
add_args => {
%App::CSVUtils::argspecsopt_field_selection,
with_code => {
summary => 'Check with Perl code',
schema => $App::CSVUtils::sch_req_str_or_code,
description => <<'_',
Code will be given the value of the cell and should return a true value if value
is valid.
_
},
with_schema => {
summary => 'Check with a Sah schema',
schema => ['any*', of=>[
['str*', min_len=>1], # string schema
['array*', max_len=>2], # an array schema
]],
completion => sub {
require Complete::Module;
my %args = @_;
Complete::Module::complete_module(
word => $args{word},
ns_prefix => "Sah::Schema::",
);
},
},
with_regex => {
schema => 're_from_str*',
},
quiet => {
schema => 'bool*',
cmdline_aliases => {q=>{}},
},
print_validated => {
summary => 'Print the validated values of each cell',
schema => 'bool*',
description => <<'_',
When validating with schema, will print each validated (possible coerced,
filtered) value of each cell.
_
},
},
add_args_rels => {
req_one => ['with_code', 'with_schema', 'with_regex'],
},
links => [
{url=>'prog:csv-check-field-values', summary=>'Check of the values of whole fields'},
],
tags => ['accepts-schema', 'accepts-regex', 'category:checking'],
examples => [
{
summary => 'Check whether the `rank` field has monotonically increasing values',
argv => ['formula.csv', '-f', 'rank', '--with-schema', 'array/num//monotonically_increasing'],
test => 0,
'x.doc.show_result' => 0,
},
],
writes_csv => 0,
on_input_data_row => sub {
my $r = shift;
# key we add to the stash
unless (defined $r->{code}) {
if ($r->{util_args}{with_schema}) {
require Data::Sah;
my $sch = $r->{util_args}{with_schema};
if (!ref($sch)) {
$sch =~ s!/!::!g;
}
$r->{code} = Data::Sah::gen_validator($sch, {return_type=>"str_errmsg+val"});
} elsif ($r->{util_args}{with_code}) {
my $code0 = compile_eval_code($r->{util_args}{with_code}, 'with_code');
$r->{code} = sub {
local $_ = $_[0]; my $res = $code0->($_);
[($res ? "":"FAIL"), $res];
};
} elsif (defined $r->{util_args}{with_regex}) {
$r->{code} = sub {
$_[0] =~ $r->{util_args}{with_regex} ? ["", $_[0]] : ["Does not match regex $r->{util_args}{with_regex}", $_[0]];
};
}
}
# key we add to the stash
unless ($r->{selected_fields_idx_array_sorted}) {
my $res = App::CSVUtils::_select_fields($r->{input_fields}, $r->{input_fields_idx}, $r->{util_args});
die $res unless $res->[0] == 100;
my $selected_fields = $res->[2][0];
my $selected_fields_idx_array = $res->[2][1];
die [412, "At least one field must be selected"]
unless @$selected_fields;
$r->{selected_fields_idx_array_sorted} = [sort { $b <=> $a } @$selected_fields_idx_array];
}
for my $idx (@{ $r->{selected_fields_idx_array_sorted} }) {
my $res = $r->{code}->( $r->{input_row}[$idx] );
if ($res->[0]) {
my $msg = "Row #$r->{input_data_rownum} field '$r->{input_fields}[$idx]': Value '$r->{input_row}[$idx]' does NOT validate: $res->[0]";
$r->{result} = [400, $msg, $r->{util_args}{quiet} ? undef : $msg];
$r->{wants_skip_files}++;
} else {
if ($r->{util_args}{print_validated}) {
print $res->[1], "\n";
}
}
}
},
after_close_input_files => sub {
my $r = shift;
$r->{result} //= [200, "OK", $r->{util_args}{quiet} ? undef : "All cells validate"];
},
);
1;
# ABSTRACT: Check the value of single cells of CSV against code/schema/regex
__END__
=pod
=encoding UTF-8
=head1 NAME
App::CSVUtils::csv_check_cell_values - Check the value of single cells of CSV against code/schema/regex
=head1 VERSION
This document describes version 1.036 of App::CSVUtils::csv_check_cell_values (from Perl distribution App-CSVUtils), released on 2025-02-04.
=head1 FUNCTIONS
=head2 csv_check_cell_values
Usage:
csv_check_cell_values(%args) -> [$status_code, $reason, $payload, \%result_meta]
Check the value of single cells of CSV against codeE<sol>schemaE<sol>regex.
Examples:
=over
=item * Check whether the `rank` field has monotonically increasing values:
csv_check_cell_values(
input_filename => "formula.csv",
include_fields => ["rank"],
with_schema => "array/num//monotonically_increasing"
);
=back
Example C<input.csv>:
ingredient,%weight
foo,81
bar,9
baz,10
Check that ingredients do not contain number:
% csv-check-cell-values input.csv -f ingredient --with-regex '/\\A[A-Za-z ]+\\z/'
Check that all %weight is between 0 and 100:
% csv-check-cell-values input.csv -f %weight --with-code '$_>0 && $_<=100'
This function is not exported.
Arguments ('*' denotes required arguments):
=over 4
=item * B<exclude_field_pat> => I<re>
Field regex pattern to exclude, takes precedence over --field-pat.
=item * B<exclude_fields> => I<array[str]>
Field names to exclude, takes precedence over --fields.
=item * B<ignore_unknown_fields> => I<bool>
When unknown fields are specified in --include-field (--field) or --exclude-field options, ignore them instead of throwing an error.
=item * B<include_field_pat> => I<re>
Field regex pattern to select, overidden by --exclude-field-pat.
=item * B<include_fields> => I<array[str]>
Field names to include, takes precedence over --exclude-field-pat.
=item * B<input_escape_char> => I<str>
Specify character to escape value in field in input CSV, will be passed to Text::CSV_XS.
Defaults to C<\\> (backslash). Overrides C<--input-tsv> option.
=item * B<input_filename> => I<filename> (default: "-")
Input CSV file.
Use C<-> to read from stdin.
Encoding of input file is assumed to be UTF-8.
( run in 1.495 second using v1.01-cache-2.11-cpan-2398b32b56e )