File Coverage

blib/lib/HTTP/Accept.pm
Criterion Covered Total %
statement 36 36 100.0
branch 17 20 85.0
condition 4 4 100.0
subroutine 3 3 100.0
pod 1 1 100.0
total 61 64 95.3


line stmt bran cond sub pod time code
1             package HTTP::Accept;
2              
3             # ABSTRACT: Parse the HTTP header 'Accept'
4              
5             our $VERSION = '0.03';
6              
7 1     1   65591 use Moo;
  1         10890  
  1         5  
8              
9             has string => ( is => 'ro', required => 1 );
10             has values => ( is => 'ro', lazy => 1, default => \&_parse_string );
11              
12             sub match {
13 54     54 1 23861 my ($self, @values_to_check) = @_;
14              
15 54 100       116 @values_to_check = grep{ defined $_ && length $_ } @values_to_check;
  70         289  
16 54 100       291 return '' if !@values_to_check;
17              
18 44 50       66 my @accepts = @{ $self->values || [] };
  44         1362  
19 44 100       465 return $values_to_check[0] if !@accepts;
20              
21 34         70 @values_to_check = map { lc $_ } @values_to_check;
  52         135  
22              
23             ACCEPT:
24 34         74 for my $accept ( @accepts ) {
25 42 100       106 return $values_to_check[0] if $accept eq '*/*';
26              
27 37         107 my ($cat, $type) = split /\//, $accept;
28              
29             VALUE:
30 37         66 for my $value ( @values_to_check ) {
31 50 100       274 return $value if $value eq $accept;
32              
33 37         80 my ($value_cat, $value_type) = split /\//, $value;
34              
35 37 100       105 next VALUE if $value_cat ne $cat;
36              
37 8 100       42 return $value if $type eq '*';
38             }
39             }
40              
41 11         43 return '';
42             }
43              
44             around BUILDARGS => sub {
45             my ($orig, $class, @args) = @_;
46            
47             return { string => $args[0] }
48             if @args == 1 && !ref $args[0];
49            
50             return $class->$orig(@args);
51             };
52              
53             sub _parse_string {
54 24     24   25873 my ($self) = @_;
55              
56 24   100     144 my @accepts = split /\s*,\s*/, $self->string // '';
57 24         38 my %weighted;
58              
59 24         49 for my $accept ( @accepts ) {
60 24         68 my ($accept_name, $quality) = split /;/, $accept;
61              
62 24   100     97 $quality //= 'q=1';
63 24 50       65 $quality = 'q=1' if $quality !~ m{q=};
64              
65 24         88 my ($weight) = $quality =~ m{q=([^;]*)};
66 24         36 push @{ $weighted{$weight} }, lc $accept_name;
  24         94  
67             }
68              
69 24 50       214 my @accept_names = map{ @{ $weighted{$_} || [] } } sort { $b <=> $a }keys %weighted;
  24         38  
  24         187  
  6         35  
70              
71 24         334 return \@accept_names;
72             }
73              
74             1;
75              
76             __END__