add repeat_between option to repeat filter
[catagits/HTML-Zoom.git] / lib / HTML / Zoom / StreamBase.pm
CommitLineData
5f74b883 1package HTML::Zoom::StreamBase;
2
3use strict;
4use warnings FATAL => 'all';
5
3cdbc13f 6sub peek {
7 my ($self) = @_;
8 if (exists $self->{_peeked}) {
9 return ($self->{_peeked});
10 }
11 if (my ($peeked) = $self->next) {
12 return ($self->{_peeked} = $peeked);
13 }
14 return;
15}
16
17sub flatten {
18 my $source_stream = shift;
19 require HTML::Zoom::CodeStream;
20 my $cur_stream;
21 HTML::Zoom::CodeStream->new({
22 code => sub {
23 return unless $source_stream;
24 my $next;
25 until (($next) = ($cur_stream ? $cur_stream->next : ())) {
3cdbc13f 26 unless (($cur_stream) = $source_stream->next) {
27 undef $source_stream; return;
28 }
29 }
3cdbc13f 30 return $next;
31 }
32 });
33}
34
35sub map {
36 my ($source_stream, $map_func) = @_;
37 require HTML::Zoom::CodeStream;
38 HTML::Zoom::CodeStream->new({
39 code => sub {
40 return unless $source_stream;
41 # If we were aiming for a "true" perl-like map then we should
42 # elegantly handle the case where the map function returns 0 events
43 # and the case where it returns >1 - if you're reading this comment
44 # because you wanted it to do that, now would be the time to fix it :)
45 if (my ($next) = $source_stream->next) {
46 #### XXXX collapsing this into a return doesn't work. what the
47 #### flying fornication ... -- mst
48 my $mapped = do { local $_ = $next; $map_func->($next) };
49 return $mapped;
50 }
51 undef $source_stream; return;
52 }
53 });
54}
55
5f74b883 561;