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