File Coverage

blib/lib/Feed/Data/Parser.pm
Criterion Covered Total %
statement 12 12 100.0
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 16 16 100.0


line stmt bran cond sub pod time code
1             package Feed::Data::Parser;
2              
3 12     12   88 use Moo;
  12         30  
  12         112  
4 12     12   5136 use Carp qw/croak/;
  12         32  
  12         579  
5              
6 12     12   6204 use Class::Load qw/load_class/;
  12         158724  
  12         738  
7 12     12   105 use Types::Standard qw/Object ScalarRef Str/;
  12         24  
  12         88  
8              
9              
10             our $VERSION = '0.01';
11              
12             has 'stream' => (
13             is => 'ro',
14             isa => ScalarRef,
15             lazy => 1,
16             );
17              
18             has 'parse_tag' => (
19             is => 'ro',
20             isa => Str,
21             lazy => 1,
22             default => sub {
23             my $self = shift;
24             my $content = $self->stream;
25             my $tag;
26             if ($$content =~ m/^([A-Za-z]+)\s*\:/) {
27             $tag = 'text';
28             } elsif ($$content =~ m/^\s*\[/) {
29             $tag = 'json';
30             } elsif ($$content =~ m/^([A-Za-z]+,)/) {
31             $tag = 'csv';
32             } else {
33             while ( $$content =~ /<(\S+)/sg) {
34             (my $t = $1) =~ tr/a-zA-Z0-9:\-\?!//cd;
35             my $first = substr $t, 0, 1;
36             $tag = $t, last unless $first eq '?' || $first eq '!';
37             }
38             }
39             croak 'Could not find the first XML element' unless $tag;
40             $tag =~ s/^,*://;
41             return $tag;
42             }
43             );
44              
45             has 'parser_type' => (
46             is => 'ro',
47             isa => Str,
48             lazy => 1,
49             default => sub {
50             my $self = shift;
51             my $tag = $self->parse_tag;
52             return 'RSS' if $tag =~ /^(?:rss|rdf)$/i;
53             return 'Atom' if $tag =~ /^feed/i;
54             return 'Meta' if $tag =~ /^html/i;
55             return 'Text' if $tag =~ /^text/;
56             return 'JSON' if $tag =~ /^json/;
57             return 'CSV' if $tag =~ /^csv/;
58             return 'Table' if $tag =~ /^table/;
59             return croak "Could not find a parser";
60             }
61             );
62              
63             has 'parse' => (
64             is => 'ro',
65             isa => Object,
66             lazy => 1,
67             default => sub {
68             my $self = shift;
69             my $type = $self->parser_type;
70             my $class = "Feed::Data::Parser::" . $type;
71             load_class($class);
72             return $class->new(content_ref => $self->stream);
73             }
74             );
75              
76             1; # End of Feed::Data