File Coverage

blib/lib/Mastodon/Types.pm
Criterion Covered Total %
statement 33 33 100.0
branch n/a
condition n/a
subroutine 11 11 100.0
pod n/a
total 44 44 100.0


line stmt bran cond sub pod time code
1             package Mastodon::Types;
2              
3 5     5   56392 use strict;
  5         12  
  5         118  
4 5     5   20 use warnings;
  5         10  
  5         204  
5              
6             our $VERSION = '0.012';
7              
8 5     5   1530 use Type::Library -base;
  5         73418  
  5         54  
9              
10 5     5   3969 use Type::Utils -all;
  5         19312  
  5         63  
11 5     5   18936 use Types::Standard qw( Str HashRef Num );
  5         166491  
  5         109  
12 5     5   7162 use Types::Path::Tiny qw( File to_File);
  5         131015  
  5         51  
13              
14 5     5   5041 use URI;
  5         14736  
  5         149  
15 5     5   3658 use DateTime;
  5         2217019  
  5         245  
16 5     5   2798 use MIME::Base64;
  5         2923  
  5         338  
17 5     5   1796 use Class::Load qw( load_class );
  5         37768  
  5         2974  
18              
19             duck_type 'UserAgent', [qw( get post delete )];
20              
21             class_type 'URI', { class => 'URI' };
22              
23             coerce 'URI', from Str, via {
24             s{^/+}{}g;
25             my $uri = URI->new((m{^https?://} ? q{} : 'https://') . $_);
26             $uri->scheme('https') unless $uri->scheme;
27             return $uri;
28             };
29              
30             # We provide our own DateTime type because the Types::DateTime distribution
31             # is currently undermaintained
32              
33             class_type 'DateTime', { class => 'DateTime' };
34              
35             coerce 'DateTime',
36             from Num,
37             via { 'DateTime'->from_epoch( epoch => $_ ) }
38             from Str,
39             via {
40             require DateTime::Format::Strptime;
41             DateTime::Format::Strptime->new(
42             pattern => '%FT%T.%3N%Z',
43             on_error => 'croak',
44             )->parse_datetime($_);
45             };
46              
47             # Validation here could be improved
48             # It is either a username if a local account, or a username@instance.tld
49             # but what characters are valid?
50             declare 'Acct', as Str;
51              
52             declare 'Image',
53             as Str, where { m{^data:image/(?:png|jpeg);base64,[a-zA-Z0-9/+=\n]+$} };
54              
55             coerce File, from Str, via {
56             require Path::Tiny;
57             return Path::Tiny::path( $_ );
58             };
59              
60             coerce 'Image',
61             from File->coercibles,
62             via {
63             my $file = to_File($_);
64             require Image::Info;
65             require MIME::Base64;
66             my $type = lc Image::Info::image_type( $file->stringify )->{file_type};
67             my $img = "data:image/$type;base64,"
68             . MIME::Base64::encode_base64( $file->slurp );
69             return $img;
70             };
71              
72             # Entity types
73              
74             my @entities = qw(
75             Status Account Instance Attachment Card Context Mention
76             Notification Relationship Report Results Error Tag Application
77             );
78              
79             foreach my $name (@entities) {
80             class_type $name, { class => "Mastodon::Entity::$name" };
81             coerce $name, from HashRef, via {
82             load_class "Mastodon::Entity::$name";
83             "Mastodon::Entity::$name"->new($_);
84             };
85             }
86              
87             role_type 'Entity', { role => 'Mastodon::Role::Entity' };
88              
89             coerce 'Instance',
90             from Str,
91             via {
92             require Mastodon::Entity::Instance;
93             Mastodon::Entity::Instance->new({
94             uri => $_,
95             });
96             };
97              
98             coerce 'Entity',
99             from HashRef,
100             via {
101             my $hash = $_;
102             my $entity;
103              
104 5     5   39 use Try::Tiny;
  5         15  
  5         622  
105             foreach my $name (@entities) {
106             $entity = try {
107             load_class "Mastodon::Entity::$name";
108             "Mastodon::Entity::$name"->new($hash);
109             };
110             last if defined $entity;
111             }
112              
113             return $entity;
114             };
115              
116             1;