File Coverage

blib/lib/Catmandu/Fix/Bind/with.pm
Criterion Covered Total %
statement 22 25 88.0
branch 3 4 75.0
condition n/a
subroutine 8 9 88.8
pod 0 3 0.0
total 33 41 80.4


line stmt bran cond sub pod time code
1             package Catmandu::Fix::Bind::with;
2              
3 1     1   1189 use Catmandu::Sane;
  1         4  
  1         7  
4              
5             our $VERSION = '1.2020';
6              
7 1     1   7 use Moo;
  1         3  
  1         6  
8 1     1   405 use Clone ();
  1         2  
  1         28  
9 1     1   6 use Catmandu::Util;
  1         2  
  1         34  
10 1     1   5 use namespace::clean;
  1         10  
  1         36  
11 1     1   783 use Catmandu::Fix::Has;
  1         3  
  1         6  
12              
13             with 'Catmandu::Fix::Bind', 'Catmandu::Fix::Bind::Group';
14              
15             has path => (fix_opt => 1);
16              
17             sub zero {
18 0     0 0 0 my ($self) = @_;
19 0         0 [];
20             }
21              
22             sub unit {
23 12     12 0 30 my ($self, $data) = @_;
24 12 100       203 defined $self->path ? Catmandu::Util::data_at($self->path, $data) : $data;
25             }
26              
27             sub bind {
28             my ($self, $mvar, $code) = @_;
29              
30             if (Catmandu::Util::is_hash_ref($mvar)) {
31             my $copy = Clone::clone($mvar);
32              
33             $copy = $code->($copy);
34              
35             if (ref($copy) eq 'reject') {
36              
37             #map { delete $mvar->{$_} } (keys %$mvar);
38             %$mvar = ();
39             }
40             else {
41             %$mvar = %$copy;
42             }
43              
44             return $mvar;
45             }
46             elsif (Catmandu::Util::is_array_ref($mvar)) {
47             my $idx = 0;
48             for my $item (@$mvar) {
49             $item = $code->($item);
50              
51             if (ref($item) eq 'reject') {
52             splice(@$mvar, $idx, 1);
53             }
54              
55             $idx++;
56             }
57             return $mvar;
58             }
59             else {
60             return $self->zero;
61             }
62             }
63              
64             sub reject {
65 2     2 0 7 my ($self, $var) = @_;
66 2 50       17 return bless $var, 'reject' if ref($var);
67 0           return bless \$var, 'reject';
68             }
69              
70             1;
71              
72             __END__
73              
74             =pod
75              
76             =head1 NAME
77              
78             Catmandu::Fix::Bind::with - a binder that computes Fix-es in the context of a path
79              
80             =head1 SYNOPSIS
81              
82             # Input data
83             data:
84             - name: patrick
85             - name: nicolas
86              
87             # Fix
88             do with(path:data)
89             if all_match(name,nicolas)
90             reject()
91             end
92             end
93              
94             # will produce
95             data:
96             - name: patrick
97              
98              
99             =head1 DESCRIPTION
100              
101             The C<with> bind allows to run fixes in the scope of a path.
102              
103             Given a deep nested data structure :
104              
105             my:
106             deep:
107             field:
108             name: James Brown
109              
110             these two fixes are equal:
111              
112             add_field(my.deep.field.style, funk)
113              
114             do with(path:my.deep.field)
115             add_field(style,funk)
116             end
117              
118             =head1 CONFIGURATION
119              
120             =head2 path
121              
122             The path to a list in the data.
123              
124             =head1 SEE ALSO
125              
126             L<Catmandu::Fix::Bind>
127              
128             =cut