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