File Coverage

blib/lib/Data/Focus.pm
Criterion Covered Total %
statement 62 62 100.0
branch 11 14 78.5
condition n/a
subroutine 15 15 100.0
pod 8 8 100.0
total 96 99 96.9


line stmt bran cond sub pod time code
1             package Data::Focus;
2 23     23   472675 use strict;
  23         54  
  23         993  
3 23     23   124 use warnings;
  23         35  
  23         697  
4 23     23   9671 use Data::Focus::Lens::Composite;
  23         254  
  23         1130  
5 23     23   163 use Carp;
  23         29  
  23         2155  
6 23     23   121 use Exporter qw(import);
  23         27  
  23         16726  
7              
8             our $VERSION = "0.01";
9              
10             our @EXPORT_OK = qw(focus);
11              
12             sub focus {
13 12775     12775 1 226171 my ($target, @lenses) = @_;
14 12775         27148 return __PACKAGE__->new(target => $target, lens => \@lenses);
15             }
16              
17             sub new {
18 12785     12785 1 25318 my ($class, %args) = @_;
19 12785 50       23392 croak "target param is mandatory" if !exists($args{target});
20 12785         12870 my $target = $args{target};
21 12785         13690 my $lenses = [];
22 12785 100       21059 if(exists($args{lens})) {
23 12784 100       23186 if(ref($args{lens}) eq "ARRAY") {
24 12782         14451 $lenses = $args{lens};
25             }else {
26 2         4 $lenses = [$args{lens}];
27             }
28             }
29 12785         18215 @$lenses = map { $class->coerce_to_lens($_) } @$lenses;
  26         35  
30 12785         35497 my $self = bless {
31             target => $target,
32             lenses => $lenses
33             }, $class;
34 12785         34624 return $self;
35             }
36              
37             sub coerce_to_lens {
38 25709     25709 1 23849 my ($class_self, $maybe_lens) = @_;
39 25709 100       22555 if(eval { $maybe_lens->isa("Data::Focus::Lens") }) {
  25709         66923  
40 25663         64157 return $maybe_lens;
41             }else {
42 46         675 require Data::Focus::Lens::HashArray::Index;
43 46         126 return Data::Focus::Lens::HashArray::Index->new(index => $maybe_lens); ## default lens (for now)
44             }
45             }
46              
47             sub into {
48 6     6 1 20 my ($self, @lenses) = @_;
49 6         15 my $deeper = ref($self)->new(
50             target => $self->{target},
51 6         13 lens => [@{$self->{lenses}}, map { $self->coerce_to_lens($_) } @lenses]
  11         16  
52             );
53 6         15 return $deeper;
54             }
55              
56             sub _apply_lenses_to_target {
57 12820     12820   16326 my ($self, $app_class, $updater, @additional_lenses) = @_;
58 12820         10258 my @lenses = (@{$self->{lenses}}, map { $self->coerce_to_lens($_) } @additional_lenses);
  12820         19725  
  12804         17860  
59 12820         33516 return Data::Focus::Lens::Composite->new(@lenses)->apply_lens(
60             $app_class,
61             $app_class->create_part_mapper($updater),
62             $self->{target}
63             );
64             }
65              
66             sub get {
67 399     399 1 3883 my ($self, @lenses) = @_;
68 399         10748 require Data::Focus::Applicative::Const::First;
69 399         1216 my $ret = $self->_apply_lenses_to_target(
70             "Data::Focus::Applicative::Const::First", undef, @lenses
71             )->get_const;
72 399 100       2826 return defined($ret) ? $$ret : undef;
73             }
74              
75             sub list {
76 562     562 1 768 my ($self, @lenses) = @_;
77 562         11533 require Data::Focus::Applicative::Const::List;
78 562         1047 my $traversed_list = $self->_apply_lenses_to_target(
79             "Data::Focus::Applicative::Const::List", undef, @lenses
80             )->get_const;
81 562 50       3915 return wantarray ? @$traversed_list : $traversed_list->[0];
82             }
83              
84             sub over {
85 11859     11859 1 9609 my $updater = pop;
86 11859         13819 my ($self, @lenses) = @_;
87 11859 50       21542 croak "updater param must be a code-ref" if ref($updater) ne "CODE";
88 11859         54523 require Data::Focus::Applicative::Identity;
89 11859         19483 return $self->_apply_lenses_to_target(
90             "Data::Focus::Applicative::Identity", $updater, @lenses
91             )->run_identity;
92             }
93              
94             sub set {
95 11837     11837 1 16977 my $datum = pop;
96 11837         9780 my $self = shift;
97 11837     17176   36553 return $self->over(@_, sub { $datum });
  17176         34517  
98             }
99              
100             1;
101             __END__