File Coverage

blib/lib/Role/MimeInfo.pm
Criterion Covered Total %
statement 12 14 85.7
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 17 19 89.4


line stmt bran cond sub pod time code
1             package Role::MimeInfo;
2              
3 1     1   63067 use 5.012;
  1         5  
4 1     1   6 use strict;
  1         3  
  1         24  
5 1     1   5 use warnings FATAL => 'all';
  1         5  
  1         44  
6              
7 1     1   321 use Moo::Role;
  1         16294  
  1         7  
8 1     1   622 use namespace::autoclean;
  0            
  0            
9              
10             use File::MimeInfo ();
11             use File::MimeInfo::Magic ();
12             use IO::Scalar ();
13             use IO::ScalarArray ();
14             use Scalar::Util ();
15             use overload ();
16              
17             =head1 NAME
18              
19             Role::MimeInfo - Bolt-on type checking against GNOME shared-mime-info
20              
21             =head1 VERSION
22              
23             Version 0.01
24              
25             =cut
26              
27             our $VERSION = '0.01';
28              
29             =head1 SYNOPSIS
30              
31             use Moo; # or Moose or Mouse or whatever
32              
33             with 'Role::MimeInfo';
34              
35             # are you ready to check some mime types???
36              
37             =head1 METHODS
38              
39             =head2 mimetype
40              
41             Proxy for L.
42              
43             =cut
44              
45             sub mimetype {
46             my (undef, $obj) = @_;
47             return unless defined $obj;
48              
49             # treat as a filename if not a ref
50             my $ref = ref $obj or return File::MimeInfo::mimetype($obj);
51             my $bl = Scalar::Util::blessed($obj);
52              
53             if ($ref eq 'GLOB' or ($bl and $ref->can('seek') and $ref->can('read'))) {
54             return File::MimeInfo::Magic::mimetype($obj);
55             }
56             elsif ($ref eq 'SCALAR') {
57             $obj = IO::Scalar->new($obj);
58             }
59             elsif ($ref eq 'ARRAY') {
60             $obj = IO::ScalarArray->new($obj);
61             }
62             elsif (my $ov = overload::Method($obj, '""')) {
63             my $tmp = $ov->($obj);
64             $obj = IO::Scalar->new(\$tmp);
65             }
66             else {
67             Carp::croak("mimetype: don't know how to dispatch $ref");
68             }
69              
70             File::MimeInfo::Magic::mimetype($obj);
71             }
72              
73             =head2 mimetype_isa
74              
75             Proxy for L with additional
76             behaviour for self-identity and recursive type checking.
77              
78             =cut
79              
80             sub mimetype_isa {
81             my (undef, $child, $ancestor) = @_;
82             return unless defined $child;
83              
84             # strip and lowercase the parameters
85             $child =~ s/^\s*([^;[:space:]]+).*?/\L$1/;
86              
87             # start queueing it up
88             my %t = ($child => 1);
89              
90             my $canon = File::MimeInfo::mimetype_canon($child);
91             $t{$canon}++ if $canon and $canon ne $child;
92              
93             if (defined $ancestor) {
94             $ancestor =~ s/^\s*([^;[:space:]]+).*?/\L$1/;
95             return 1 if $t{$ancestor};
96              
97             # canonicalize the ancestor and try again
98             $ancestor = File::MimeInfo::mimetype_canon($ancestor) || $ancestor;
99             return 1 if $t{$ancestor};
100             }
101              
102             # now we recursively (okay, iteratively) check
103             my @q = ($child);
104             do {
105             # this second loop is necessary because we get a list here
106             for my $t (File::MimeInfo::mimetype_isa(shift @q)) {
107             $t = lc $t; # JIC
108             push @q, $t unless defined $t{$t};
109             $t{$t}++;
110             }
111             } while @q;
112              
113             # just give true or false if an ancestor was supplied
114             return !!$t{lc $ancestor} if defined $ancestor;
115              
116             # otherwise just cough up the whole pile
117             return sort keys %t;
118             }
119              
120             =head1 SEE ALSO
121              
122             =over 4
123              
124             =item
125              
126             L
127              
128             =item
129              
130             L
131              
132             =back
133              
134             =head1 AUTHOR
135              
136             Dorian Taylor, C<< >>
137              
138             =head1 TODO
139              
140             =over 4
141              
142             =item
143              
144             Expose the rest of the interface of L in a reasonable
145             way.
146              
147             =back
148              
149             =head1 BUGS
150              
151             Please report any bugs or feature requests to
152             L .
153              
154             =head1 LICENSE AND COPYRIGHT
155              
156             Copyright 2017 Dorian Taylor.
157              
158             Licensed under the Apache License, Version 2.0 (the "License"); you
159             may not use this file except in compliance with the License. You may
160             obtain a copy of the License at
161             L.
162              
163             Unless required by applicable law or agreed to in writing, software
164             distributed under the License is distributed on an "AS IS" BASIS,
165             WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
166             implied. See the License for the specific language governing
167             permissions and limitations under the License.
168              
169             =cut
170              
171             1; # End of Role::MimeInfo