<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">package TAP::Parser::SourceHandler;

use strict;
use warnings;

use TAP::Parser::Iterator ();
use base 'TAP::Object';

=head1 NAME

TAP::Parser::SourceHandler - Base class for different TAP source handlers

=head1 VERSION

Version 3.50

=cut

our $VERSION = '3.50';

=head1 SYNOPSIS

  # abstract class - don't use directly!
  # see TAP::Parser::IteratorFactory for general usage

  # must be sub-classed for use
  package MySourceHandler;
  use base 'TAP::Parser::SourceHandler';
  sub can_handle    { return $confidence_level }
  sub make_iterator { return $iterator }

  # see example below for more details

=head1 DESCRIPTION

This is an abstract base class for L&lt;TAP::Parser::Source&gt; handlers / handlers.

A C&lt;TAP::Parser::SourceHandler&gt; does whatever is necessary to produce &amp; capture
a stream of TAP from the I&lt;raw&gt; source, and package it up in a
L&lt;TAP::Parser::Iterator&gt; for the parser to consume.

C&lt;SourceHandlers&gt; must implement the I&lt;source detection &amp; handling&gt; interface
used by L&lt;TAP::Parser::IteratorFactory&gt;.  At 2 methods, the interface is pretty
simple: L&lt;/can_handle&gt; and L&lt;/make_source&gt;.

Unless you're writing a new L&lt;TAP::Parser::SourceHandler&gt;, a plugin, or
subclassing L&lt;TAP::Parser&gt;, you probably won't need to use this module directly.

=head1 METHODS

=head2 Class Methods

=head3 C&lt;can_handle&gt;

I&lt;Abstract method&gt;.

  my $vote = $class-&gt;can_handle( $source );

C&lt;$source&gt; is a L&lt;TAP::Parser::Source&gt;.

Returns a number between C&lt;0&gt; &amp; C&lt;1&gt; reflecting how confidently the raw source
can be handled.  For example, C&lt;0&gt; means the source cannot handle it, C&lt;0.5&gt;
means it may be able to, and C&lt;1&gt; means it definitely can.  See
L&lt;TAP::Parser::IteratorFactory/detect_source&gt; for details on how this is used.

=cut

sub can_handle {
    my ( $class, $args ) = @_;
    $class-&gt;_croak(
        "Abstract method 'can_handle' not implemented for $class!");
    return;
}

=head3 C&lt;make_iterator&gt;

I&lt;Abstract method&gt;.

  my $iterator = $class-&gt;make_iterator( $source );

C&lt;$source&gt; is a L&lt;TAP::Parser::Source&gt;.

Returns a new L&lt;TAP::Parser::Iterator&gt; object for use by the L&lt;TAP::Parser&gt;.
C&lt;croak&gt;s on error.

=cut

sub make_iterator {
    my ( $class, $args ) = @_;
    $class-&gt;_croak(
        "Abstract method 'make_iterator' not implemented for $class!");
    return;
}
1;

__END__

=head1 SUBCLASSING

Please see L&lt;TAP::Parser/SUBCLASSING&gt; for a subclassing overview, and any
of the subclasses that ship with this module as an example.  What follows is
a quick overview.

Start by familiarizing yourself with L&lt;TAP::Parser::Source&gt; and
L&lt;TAP::Parser::IteratorFactory&gt;.  L&lt;TAP::Parser::SourceHandler::RawTAP&gt; is
the easiest sub-class to use as an example.

It's important to point out that if you want your subclass to be automatically
used by L&lt;TAP::Parser&gt; you'll have to and make sure it gets loaded somehow.
If you're using L&lt;prove&gt; you can write an L&lt;App::Prove&gt; plugin.  If you're
using L&lt;TAP::Parser&gt; or L&lt;TAP::Harness&gt; directly (e.g. through a custom script,
L&lt;ExtUtils::MakeMaker&gt;, or L&lt;Module::Build&gt;) you can use the C&lt;config&gt; option
which will cause L&lt;TAP::Parser::IteratorFactory/load_sources&gt; to load your
subclass).

Don't forget to register your class with
L&lt;TAP::Parser::IteratorFactory/register_handler&gt;.

=head2 Example

  package MySourceHandler;

  use strict;

  use MySourceHandler; # see TAP::Parser::SourceHandler
  use TAP::Parser::IteratorFactory;

  use base 'TAP::Parser::SourceHandler';

  TAP::Parser::IteratorFactory-&gt;register_handler( __PACKAGE__ );

  sub can_handle {
      my ( $class, $src ) = @_;
      my $meta   = $src-&gt;meta;
      my $config = $src-&gt;config_for( $class );

      if ($config-&gt;{accept_all}) {
          return 1.0;
      } elsif (my $file = $meta-&gt;{file}) {
          return 0.0 unless $file-&gt;{exists};
          return 1.0 if $file-&gt;{lc_ext} eq '.tap';
          return 0.9 if $file-&gt;{shebang} &amp;&amp; $file-&gt;{shebang} =~ /^#!.+tap/;
          return 0.5 if $file-&gt;{text};
          return 0.1 if $file-&gt;{binary};
      } elsif ($meta-&gt;{scalar}) {
          return 0.8 if $$raw_source_ref =~ /\d\.\.\d/;
          return 0.6 if $meta-&gt;{has_newlines};
      } elsif ($meta-&gt;{array}) {
          return 0.8 if $meta-&gt;{size} &lt; 5;
          return 0.6 if $raw_source_ref-&gt;[0] =~ /foo/;
          return 0.5;
      } elsif ($meta-&gt;{hash}) {
          return 0.6 if $raw_source_ref-&gt;{foo};
          return 0.2;
      }

      return 0;
  }

  sub make_iterator {
      my ($class, $source) = @_;
      # this is where you manipulate the source and
      # capture the stream of TAP in an iterator
      # either pick a TAP::Parser::Iterator::* or write your own...
      my $iterator = TAP::Parser::Iterator::Array-&gt;new([ 'foo', 'bar' ]);
      return $iterator;
  }

  1;

=head1 AUTHORS

TAPx Developers.

Source detection stuff added by Steve Purkis

=head1 SEE ALSO

L&lt;TAP::Object&gt;,
L&lt;TAP::Parser&gt;,
L&lt;TAP::Parser::Source&gt;,
L&lt;TAP::Parser::Iterator&gt;,
L&lt;TAP::Parser::IteratorFactory&gt;,
L&lt;TAP::Parser::SourceHandler::Executable&gt;,
L&lt;TAP::Parser::SourceHandler::Perl&gt;,
L&lt;TAP::Parser::SourceHandler::File&gt;,
L&lt;TAP::Parser::SourceHandler::Handle&gt;,
L&lt;TAP::Parser::SourceHandler::RawTAP&gt;

=cut

</pre></body></html>