1 package HTML::Zoom::StreamUtils;
4 use warnings FATAL => 'all';
5 use base qw(HTML::Zoom::SubObject);
9 use HTML::Zoom::CodeStream;
10 use HTML::Zoom::FilterStream;
11 use HTML::Zoom::ArrayStream;
13 sub stream_from_code {
14 my ($self, $code) = @_;
15 HTML::Zoom::CodeStream->new({
17 zconfig => $self->_zconfig,
21 sub stream_from_array {
24 HTML::Zoom::ArrayStream->new({
26 zconfig => $self->_zconfig,
31 shift->stream_from_array(@_)->flatten;
34 sub stream_from_proto {
35 my ($self, $proto) = @_;
38 return $self->stream_from_array({
40 raw => $self->_zconfig->parser->html_escape($proto)
42 } elsif ($ref eq 'ARRAY') {
43 return $self->stream_from_array(@$proto);
44 } elsif ($ref eq 'CODE') {
46 } elsif ($ref eq 'SCALAR') {
47 return $self->_zconfig->parser->html_to_stream($$proto);
48 } elsif (Scalar::Util::blessed($proto) && $proto->can('to_stream')) {
49 my $stream = $proto->to_stream;
50 return $self->stream_from_code(sub { $stream->next });
52 die "Don't know how to turn $proto (ref $ref) into a stream";
55 sub wrap_with_filter {
56 my ($self, $stream, $match, $filter) = @_;
57 HTML::Zoom::FilterStream->new({
61 zconfig => $self->_zconfig,
68 while (my ($evt) = $stream->next) { push @array, $evt }
72 sub flatten_stream_of_streams {
73 my ($self, $source_stream) = @_;
75 HTML::Zoom::CodeStream->new({
77 return unless $source_stream;
79 until (($next) = ($cur_stream ? $cur_stream->next : ())) {
80 unless (($cur_stream) = $source_stream->next) {
81 undef $source_stream; return;