File Coverage

blib/lib/HashDataRole/Source/Iterator.pm
Criterion Covered Total %
statement 56 59 94.9
branch 21 26 80.7
condition 1 2 50.0
subroutine 11 12 91.6
pod 0 7 0.0
total 89 106 83.9


line stmt bran cond sub pod time code
1             package HashDataRole::Source::Iterator;
2              
3 3     3   358258 use strict;
  3         8  
  3         112  
4 3     3   54 use 5.010001;
  3         10  
5 3     3   479 use Role::Tiny;
  3         5179  
  3         20  
6 3     3   1147 use Role::Tiny::With;
  3         249  
  3         2191  
7             with 'HashDataRole::Spec::Basic';
8              
9             our $AUTHORITY = 'cpan:PERLANCAR'; # AUTHORITY
10             our $DATE = '2024-11-04'; # DATE
11             our $DIST = 'HashDataRoles-Standard'; # DIST
12             our $VERSION = '0.005'; # VERSION
13              
14             sub _new {
15 1     1   5 my ($class, %args) = @_;
16              
17 1 50       5 my $gen_iterator = delete $args{gen_iterator} or die "Please specify 'gen_iterator' argument";
18 1   50     7 my $gen_iterator_params = delete $args{gen_iterator_params} // {};
19              
20 1 50       5 die "Unknown argument(s): ". join(", ", sort keys %args)
21             if keys %args;
22              
23 1         11 bless {
24             gen_iterator => $gen_iterator,
25             gen_iterator_params => $gen_iterator_params,
26             iterator => undef,
27             pos => 0,
28             # buf => '', # exists when there is a buffer
29             }, $class;
30             }
31              
32             sub get_next_item {
33 23     23 0 108 my $self = shift;
34 23 50       64 $self->reset_iterator unless $self->{iterator};
35 23 100       55 if (exists $self->{buf}) {
36 18         54 $self->{pos}++;
37 18         44 return delete $self->{buf};
38             } else {
39 5         19 my ($key, $val) = $self->{iterator}->();
40 5 100       55 die "StopIteration" unless defined $key;
41 4         11 $self->{pos}++;
42 4         32 return [$key, $val];
43             }
44             }
45              
46             sub has_next_item {
47 22     22 0 49 my $self = shift;
48 22 50       58 if (exists $self->{buf}) {
49 0         0 return 1;
50             }
51 22 50       83 $self->reset_iterator unless $self->{iterator};
52 22         62 my ($key,$val) = $self->{iterator}->();
53 22 100       76 return 0 unless defined $key;
54 18         45 $self->{buf} = [$key,$val];
55 18         48 1;
56             }
57              
58             sub reset_iterator {
59 10     10 0 37 my $self = shift;
60 10         17 $self->{iterator} = $self->{gen_iterator}->(%{ $self->{gen_iterator_params} });
  10         55  
61 10         32 $self->{pos} = 0;
62             }
63              
64             sub get_iterator_pos {
65 0     0 0 0 my $self = shift;
66 0         0 $self->{pos};
67             }
68              
69             sub get_item_at_key {
70 3     3 0 11 my ($self, $key) = @_;
71 3         12 $self->reset_iterator;
72 3         5 while (1) {
73 7 100       35 return unless $self->has_next_item;
74 6         15 my $item = $self->get_next_item;
75 6 100       63 return $item if $item->[0] eq $key;
76             }
77             }
78              
79             sub has_item_at_key {
80 3     3 0 1019 my ($self, $key) = @_;
81 3         15 $self->reset_iterator;
82 3         5 while (1) {
83 7 100       18 return 0 unless $self->has_next_item;
84 6         18 my $item = $self->get_next_item;
85 6 100       58 return 1 if $item->[0] eq $key;
86             }
87             }
88              
89             sub get_all_keys {
90 1     1 0 4 my ($self) = @_;
91 1         6 $self->reset_iterator;
92 1         3 my @keys;
93 1         2 while (1) {
94 4 100       11 last unless $self->has_next_item;
95 3         13 my $item = $self->get_next_item;
96 3         9 push @keys, $item->[0];
97             }
98 1         11 @keys;
99             }
100              
101             1;
102             # ABSTRACT: Get hash data from an iterator
103              
104             __END__