factor out ArrayStream, update new stream types to respect peek
[catagits/HTML-Zoom.git] / lib / HTML / Zoom / StreamBase.pm
index 7584ed6..a733656 100644 (file)
@@ -2,5 +2,75 @@ package HTML::Zoom::StreamBase;
 
 use strict;
 use warnings FATAL => 'all';
+use HTML::Zoom::MatchWithoutFilter;
+
+sub _zconfig { shift->{_zconfig} }
+
+sub peek {
+  my ($self) = @_;
+  if (exists $self->{_peeked}) {
+    return ($self->{_peeked});
+  }
+  if (my ($peeked) = $self->_next) {
+    return ($self->{_peeked} = $peeked);
+  }
+  return;
+}
+
+sub next {
+  my ($self) = @_;
+
+  # peeked entry so return that
+
+  if (exists $self->{_peeked}) {
+    return (delete $self->{_peeked});
+  }
+
+  $self->_next;
+}
+
+
+sub flatten {
+  my $self = shift;
+  require HTML::Zoom::FlattenedStream;
+  HTML::Zoom::FlattenedStream->new({
+    source => $self,
+    zconfig => $self->_zconfig
+  });
+}
+
+sub map {
+  my ($self, $mapper) = @_;
+  require HTML::Zoom::MappedStream;
+  HTML::Zoom::MappedStream->new({
+    source => $self, mapper => $mapper, zconfig => $self->_zconfig
+  });
+}
+
+sub with_filter {
+  my ($self, $selector, $filter) = @_;
+  my $match = $self->_parse_selector($selector);
+  $self->_zconfig->stream_utils->wrap_with_filter($self, $match, $filter);
+}
+
+sub select {
+  my ($self, $selector) = @_;
+  my $match = $self->_parse_selector($selector);
+  return HTML::Zoom::MatchWithoutFilter->construct(
+    $self, $match, $self->_zconfig->filter_builder,
+  );
+}
+
+sub _parse_selector {
+  my ($self, $selector) = @_;
+  return $selector if ref($selector); # already a match sub
+  $self->_zconfig->selector_parser->parse_selector($selector);
+}
+
+sub apply {
+  my ($self, $code) = @_;
+  local $_ = $self;
+  $self->$code;
+}
 
 1;