File Coverage

blib/lib/Data/Focus.pm
Criterion Covered Total %
statement 61 61 100.0
branch 13 16 81.2
condition 2 3 66.6
subroutine 16 16 100.0
pod 8 8 100.0
total 100 104 96.1


line stmt bran cond sub pod time code
1             package Data::Focus;
2 23     23   349734 use strict;
  23         51  
  23         824  
3 23     23   97 use warnings;
  23         31  
  23         577  
4 23     23   8229 use Data::Focus::Lens::Composite;
  23         201  
  23         537  
5 23     23   119 use Carp;
  23         27  
  23         1807  
6 23     23   102 use Exporter qw(import);
  23         28  
  23         527  
7 23     23   93 use Scalar::Util ();
  23         29  
  23         13090  
8              
9             our $VERSION = "0.02";
10              
11             our @EXPORT_OK = qw(focus);
12              
13             sub focus {
14 12775     12775 1 236108 my ($target, @lenses) = @_;
15 12775         27998 return __PACKAGE__->new(target => $target, lens => \@lenses);
16             }
17              
18             sub new {
19 12785     12785 1 25889 my ($class, %args) = @_;
20 12785 50       25020 croak "target param is mandatory" if !exists($args{target});
21 12785         13402 my $target = $args{target};
22 12785 100       32627 my $lenses = exists($args{lens}) ?
    100          
23             (ref($args{lens}) eq "ARRAY" ? $args{lens} : [$args{lens}])
24             : [];
25 12785         20222 $_ = $class->coerce_to_lens($_) foreach @$lenses;
26 12785         34825 my $self = bless {
27             target => $target,
28             lenses => $lenses
29             }, $class;
30 12785         35825 return $self;
31             }
32              
33             sub coerce_to_lens {
34 12860     12860 1 14115 my (undef, $maybe_lens) = @_;
35 12860 100 66     73451 if(Scalar::Util::blessed($maybe_lens) && $maybe_lens->isa("Data::Focus::Lens")) {
36 12814         33806 return $maybe_lens;
37             }else {
38 46         632 require Data::Focus::Lens::HashArray::Index;
39 46         203 return Data::Focus::Lens::HashArray::Index->new(index => $maybe_lens); ## default lens (for now)
40             }
41             }
42              
43             sub into {
44 6     6 1 17 my ($self, @lenses) = @_;
45 6         5 unshift @lenses, @{$self->{lenses}};
  6         13  
46 6         20 my $deeper = ref($self)->new(
47             target => $self->{target},
48             lens => \@lenses,
49             );
50 6         40 return $deeper;
51             }
52              
53             sub _apply_lenses_to_target {
54 12820     12820   17672 my ($self, $app_class, $updater, @additional_lenses) = @_;
55 12820         10279 my @lenses = (@{$self->{lenses}}, map { $self->coerce_to_lens($_) } @additional_lenses);
  12820         21707  
  12804         19223  
56 12820 100       19049 if(@lenses == 1) {
57 12737         34877 return $lenses[0]->apply_lens(
58             $app_class, $app_class->create_part_mapper($updater), $self->{target}
59             );
60             }else {
61 83         340 return Data::Focus::Lens::Composite->apply_composite_lens(
62             \@lenses,
63             $app_class,
64             $app_class->create_part_mapper($updater),
65             $self->{target}
66             );
67             }
68             }
69              
70             sub get {
71 399     399 1 3175 my ($self, @lenses) = @_;
72 399         9454 require Data::Focus::Applicative::Const::First;
73 399         843 my $ret = $self->_apply_lenses_to_target(
74             "Data::Focus::Applicative::Const::First", undef, @lenses
75             )->get_const;
76 399 100       2562 return defined($ret) ? $$ret : undef;
77             }
78              
79             sub list {
80 562     562 1 826 my ($self, @lenses) = @_;
81 562         10346 require Data::Focus::Applicative::Const::List;
82 562         1187 my $traversed_list = $self->_apply_lenses_to_target(
83             "Data::Focus::Applicative::Const::List", undef, @lenses
84             )->get_const;
85 562 50       4089 return wantarray ? @$traversed_list : $traversed_list->[0];
86             }
87              
88             sub over {
89 11859     11859 1 10502 my $updater = pop;
90 11859         14390 my ($self, @lenses) = @_;
91 11859 50       21257 croak "updater param must be a code-ref" if ref($updater) ne "CODE";
92 11859         56431 require Data::Focus::Applicative::Identity;
93 11859         20585 return $self->_apply_lenses_to_target(
94             "Data::Focus::Applicative::Identity", $updater, @lenses
95             )->run_identity;
96             }
97              
98             sub set {
99 11837     11837 1 14537 my $datum = pop;
100 11837         10032 my $self = shift;
101 11837     17176   37240 return $self->over(@_, sub { $datum });
  17176         37142  
102             }
103              
104             1;
105             __END__