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 13     13   100 use Moo;
  13         31  
  13         121  
4 13     13   5728 use Carp qw/croak/;
  13         49  
  13         657  
5              
6 13     13   5784 use Class::Load qw/load_class/;
  13         175910  
  13         788  
7 13     13   105 use Types::Standard qw/Object ScalarRef Str/;
  13         30  
  13         96  
8              
9             has 'stream' => (
10             is => 'ro',
11             isa => ScalarRef,
12             lazy => 1,
13             );
14              
15             has 'parse_tag' => (
16             is => 'ro',
17             isa => Str,
18             lazy => 1,
19             default => sub {
20             my $self = shift;
21             my $content = $self->stream;
22             my $tag;
23             if ($$content =~ m/^([A-Za-z]+)\s*\:/) {
24             $tag = 'text';
25             } elsif ($$content =~ m/^\s*\[/) {
26             $tag = 'json';
27             } elsif ($$content =~ m/^([A-Za-z]+,)/) {
28             $tag = 'csv';
29             } elsif ($$content =~ m/---/) {
30             $tag = 'yaml';
31             } else {
32             while ( $$content =~ /<(\S+)/sg) {
33             (my $t = $1) =~ tr/a-zA-Z0-9:\-\?!//cd;
34             my $first = substr $t, 0, 1;
35             $tag = $t, last unless $first eq '?' || $first eq '!';
36             }
37             }
38             croak 'Could not find the first XML element' unless $tag;
39             $tag =~ s/^,*://;
40             return $tag;
41             }
42             );
43              
44             has 'parser_type' => (
45             is => 'ro',
46             isa => Str,
47             lazy => 1,
48             default => sub {
49             my $self = shift;
50             my $tag = $self->parse_tag;
51             return 'RSS' if $tag =~ /^(?:rss|rdf)$/i;
52             return 'Atom' if $tag =~ /^feed/i;
53             return 'Meta' if $tag =~ /^html/i;
54             return 'Text' if $tag =~ /^text/;
55             return 'JSON' if $tag =~ /^json/;
56             return 'CSV' if $tag =~ /^csv/;
57             return 'Table' if $tag =~ /^table/;
58             return 'YAML' if $tag =~ /^yaml/;
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