fix bug where first event isn't passed to filter during collect w/out inside
[catagits/HTML-Zoom.git] / lib / HTML / Zoom / StreamUtils.pm
CommitLineData
d80786d0 1package HTML::Zoom::StreamUtils;
2
1cf03540 3use strictures 1;
d80786d0 4use base qw(HTML::Zoom::SubObject);
5
bf5a23d0 6use Scalar::Util ();
7
d80786d0 8use HTML::Zoom::CodeStream;
9use HTML::Zoom::FilterStream;
b5a48c47 10use HTML::Zoom::ArrayStream;
d80786d0 11
12sub stream_from_code {
13 my ($self, $code) = @_;
14 HTML::Zoom::CodeStream->new({
15 code => $code,
16 zconfig => $self->_zconfig,
17 })
18}
19
20sub stream_from_array {
21 my $self = shift;
22 my @array = @_;
b5a48c47 23 HTML::Zoom::ArrayStream->new({
24 array => \@array,
25 zconfig => $self->_zconfig,
26 })
d80786d0 27}
28
29sub stream_concat {
30 shift->stream_from_array(@_)->flatten;
31}
32
33sub stream_from_proto {
34 my ($self, $proto) = @_;
35 my $ref = ref $proto;
36 if (not $ref) {
37 return $self->stream_from_array({
38 type => 'TEXT',
39 raw => $self->_zconfig->parser->html_escape($proto)
40 });
41 } elsif ($ref eq 'ARRAY') {
42 return $self->stream_from_array(@$proto);
43 } elsif ($ref eq 'CODE') {
7c631a27 44 return $proto->();
d80786d0 45 } elsif ($ref eq 'SCALAR') {
46 return $self->_zconfig->parser->html_to_stream($$proto);
c9e76777 47 } elsif (Scalar::Util::blessed($proto) && $proto->can('to_stream')) {
48 my $stream = $proto->to_stream;
6d0f20a6 49 return $self->stream_from_code(sub { $stream->next });
d80786d0 50 }
51 die "Don't know how to turn $proto (ref $ref) into a stream";
52}
53
54sub wrap_with_filter {
55 my ($self, $stream, $match, $filter) = @_;
56 HTML::Zoom::FilterStream->new({
57 stream => $stream,
58 match => $match,
59 filter => $filter,
60 zconfig => $self->_zconfig,
61 })
62}
63
bf5a23d0 64sub stream_to_array {
65 my $stream = $_[1];
66 my @array;
67 while (my ($evt) = $stream->next) { push @array, $evt }
68 return @array;
69}
70
6d0f20a6 71sub flatten_stream_of_streams {
72 my ($self, $source_stream) = @_;
73 my $cur_stream;
74 HTML::Zoom::CodeStream->new({
75 code => sub {
76 return unless $source_stream;
77 my $next;
78 until (($next) = ($cur_stream ? $cur_stream->next : ())) {
79 unless (($cur_stream) = $source_stream->next) {
80 undef $source_stream; return;
81 }
82 }
83 return $next;
84 }
85 });
86}
87
d80786d0 881;