File Coverage

blib/lib/Catmandu/Fix/mapping.pm
Criterion Covered Total %
statement 47 47 100.0
branch 2 2 100.0
condition n/a
subroutine 12 12 100.0
pod n/a
total 61 61 100.0


line stmt bran cond sub pod time code
1             package Catmandu::Fix::mapping;
2              
3 1     1   115037 use Catmandu::Sane;
  1         4  
  1         7  
4              
5 1     1   1010 use Catmandu::Importer::CSV;
  1         4  
  1         42  
6 1     1   9 use Catmandu::Util::Path qw(as_path);
  1         2  
  1         57  
7 1     1   6 use Catmandu::Util qw(is_value);
  1         2  
  1         43  
8 1     1   6 use Clone qw(clone);
  1         3  
  1         39  
9 1     1   7 use Moo;
  1         2  
  1         6  
10 1     1   387 use namespace::clean;
  1         3  
  1         5  
11 1     1   936 use Catmandu::Fix::Has;
  1         3  
  1         8  
12              
13             with 'Catmandu::Fix::Builder';
14              
15             has file => (fix_arg => 1);
16             has keep => (fix_opt => 1);
17             has csv_args => (fix_opt => 'collect');
18             has dictionary => (is => 'lazy', init_arg => undef);
19              
20             sub _build_dictionary {
21 5     5   43 my ($self) = @_;
22             Catmandu::Importer::CSV->new(
23 5         112 %{$self->csv_args},
24             file => $self->file,
25             header => 0,
26             fields => ['key', 'val'],
27             )->reduce(
28             {},
29             sub {
30 25     25   42 my ($dict, $pair) = @_;
31 25         62 $dict->{$pair->{key}} = $pair->{val};
32 25         59 $dict;
33             }
34 5         8 );
35             }
36              
37             sub _build_fixer {
38 5     5   49 my ($self) = @_;
39              
40 5         81 my $dict = $self->dictionary;
41 5         24 my $keep = $self->keep;
42              
43             sub {
44 5     5   10 my $data = $_[0];
45              
46 5         21 foreach my $k (keys %$dict) {
47 25         88 my $old_path = as_path($k);
48 25         1692 my $new_path = as_path($dict->{$k});
49              
50 25         464 my $getter = $old_path->getter;
51 25         151 my $deleter = $old_path->deleter;
52 25         533 my $creator = $new_path->creator;
53              
54 25         55 my $values = [map {clone($_)} @{$getter->($data)}];
  7         45  
  25         487  
55 25 100       369 $deleter->($data) unless $keep;
56 25         723 $creator->($data, shift @$values) while @$values;
57             }
58              
59 5         107 $data;
60 5         47 };
61             }
62              
63             1;
64              
65             __END__
66              
67             =pod
68              
69             =head1 NAME
70              
71             Catmandu::Fix::mapping - move several fields by a lookup table
72              
73             =head1 SYNOPSIS
74              
75             # field_mapping.csv
76             # AU,author
77             # TI,title
78             # PU,publisher
79             # Y,year
80              
81             # fields found in the field_mapping.csv will be replaced
82             # {AU => "Einstein"}
83             mapping(field_mapping.csv)
84             # {author => "Einstein"}
85              
86             # fields found in the field_mapping.csv with keep option will be copied
87             # {AU => "Einstein"}
88             mapping(field_mapping.csv, keep: 1)
89             # {AU => => "Einstein", author => "Einstein"}
90              
91             # values not found will be kept
92             # {foo => {bar => 232}}
93             mapping(field_mapping.csv)
94             # {foo => {bar => 232}}
95              
96             # in case you have a different seperator
97             mapping(field_mapping.csv, sep_char: |)
98              
99             =head1 SEE ALSO
100              
101             L<Catmandu::Fix>, L<Catmandu::Fix::lookup>
102              
103             =cut