File Coverage

blib/lib/Yukki/Types.pm
Criterion Covered Total %
statement 29 29 100.0
branch n/a
condition n/a
subroutine 10 10 100.0
pod n/a
total 39 39 100.0


line stmt bran cond sub pod time code
1             package Yukki::Types;
2             $Yukki::Types::VERSION = '0.99_01'; # TRIAL
3              
4 3     3   32 $Yukki::Types::VERSION = '0.9901';use v5.24;
  3         10  
5 3     3   14 use utf8;
  3         6  
  3         22  
6              
7 3         18 use Type::Library -base, -declare => qw(
8             LoginName AccessLevel
9             NavigationLinks NavigationMenuMap
10             BaseURL BaseURLEnum BreadcrumbLinks RepositoryMap
11             PluginConfig PluginList
12             EmailAddress YukkiSettings
13             YukkiWebSettings YukkiSettingsAnonymous
14 3     3   110 );
  3         7  
15 3     3   5072 use Type::Utils qw( declare as where message coerce enum from via class_type );
  3         10  
  3         15  
16              
17 3     3   3143 use Types::Standard qw( Str Int ArrayRef Maybe HashRef Dict );
  3         6  
  3         17  
18 3     3   4574 use Types::URI qw( Uri );
  3         165223  
  3         31  
19              
20 3     3   2554 use Email::Address;
  3         45554  
  3         153  
21 3     3   24 use List::Util qw( first );
  3         6  
  3         242  
22 3     3   1311 use List::MoreUtils qw( all );
  3         12317  
  3         43  
23              
24 3     3   2543 use namespace::clean;
  3         6556  
  3         24  
25              
26             # ABSTRACT: standard types for use in Yukki
27              
28              
29             declare LoginName,
30             as Str,
31             where { /^[a-z0-9]+$/ },
32             message { "login name $_ must only contain letters and numbers" };
33              
34              
35             enum AccessLevel, [qw( read write none )];
36              
37              
38             declare NavigationLinks,
39             as ArrayRef[
40             Dict[
41             label => Str,
42             href => Str|Uri,
43             sort => Maybe[Int],
44             ],
45             ];
46              
47              
48             declare NavigationMenuMap,
49             as HashRef[ NavigationLinks ];
50              
51              
52             enum BaseURLEnum, [qw( SCRIPT_NAME REWRITE )];
53              
54             declare BaseURL, as BaseURLEnum|Uri;
55              
56             coerce BaseURL,
57             from Str,
58             via {
59             $_ !~ /^(?:SCRIPT_NAME|REWRITE)$/
60             && URI->new($_)
61             };
62              
63              
64             declare BreadcrumbLinks,
65             as ArrayRef[
66             Dict[
67             label => Str,
68             href => Str,
69             ],
70             ];
71              
72              
73             my $Repository = class_type 'Yukki::Settings::Repository';
74             declare RepositoryMap,
75             as HashRef[$Repository];
76              
77             coerce RepositoryMap,
78             from HashRef,
79             via {
80             my $source = $_;
81             +{
82             map { $_ => Yukki::Settings::Repository->new($source->{$_}) }
83             keys %$source
84             }
85             };
86              
87              
88             declare PluginConfig,
89             as ArrayRef[HashRef],
90             where { all { defined $_->{module} } @$_ };
91              
92              
93             my $Plugin = class_type 'Yukki::Web::Plugin';
94             declare PluginList,
95             as ArrayRef[$Plugin],
96             message {
97             return 'It is not an array of objects.' unless ref $_ eq 'ARRAY';
98             my $bad = first { not blessed $_ or not $_->isa('Yukki::Web::Plugin') }
99             @$_;
100             $bad = blessed $bad if blessed $bad;
101             return "It contains $bad, which is not a Yukki::Web::Plugin.";
102             };
103              
104              
105             class_type EmailAddress, { class => 'Email::Address' };
106             coerce EmailAddress,
107             from Str,
108             via { (Email::Address->parse($_))[0] };
109              
110              
111             class_type YukkiSettings, { class => 'Yukki::Settings' };
112             coerce YukkiSettings,
113             from HashRef,
114             via { Yukki::Settings->new($_) };
115              
116              
117             class_type YukkiWebSettings, { class => 'Yukki::Web::Settings' };
118             coerce YukkiWebSettings,
119             from HashRef,
120             via { Yukki::Web::Settings->new($_) };
121              
122              
123             class_type YukkiSettingsAnonymous, { class => 'Yukki::Settings::Anonymous' };
124             coerce YukkiSettingsAnonymous,
125             from HashRef,
126             via { Yukki::Settings::Anonymous->new($_) };
127              
128             1;
129              
130             __END__
131              
132             =pod
133              
134             =encoding UTF-8
135              
136             =head1 NAME
137              
138             Yukki::Types - standard types for use in Yukki
139              
140             =head1 VERSION
141              
142             version 0.99_01
143              
144             =head1 SYNOPSIS
145              
146             use Yukki::Types qw( LoginName AccessLevel );
147              
148             has login_name => ( isa => LoginName );
149             has access_level => ( isa => AccessLevel );
150              
151             =head1 DESCRIPTION
152              
153             A standard type library for Yukki.
154              
155             =head1 TYPES
156              
157             =head2 LoginName
158              
159             This is a valid login name. Login names may only contain letters and numbers, as of this writing.
160              
161             =head2 AccessLevel
162              
163             This is a valid access level. This includes any of the following values:
164              
165             read
166             write
167             none
168              
169             =head2 NavigationLinks
170              
171             This is an array of hashes formatted like:
172              
173             {
174             label => 'Label',
175             href => '/link/to/somewhere',
176             sort => 40,
177             }
178              
179             =head2 NavigationMenuMap
180              
181             This is a hash of L</NavigationLinks>.
182              
183             =head2 BaseURL
184              
185             This is either an absolute URL or the words C<SCRIPT_NAME> or C<REWRITE>.
186              
187             =head2 BreadcrumbLinks
188              
189             This is an array of hashes formatted like:
190              
191             {
192             label => 'Label',
193             href => '/link/to/somewhere',
194             }
195              
196             =head2 RepositoryMap
197              
198             This is a hash of L<Yukki::Settings::Repository> objects.
199              
200             =head2 PluginConfig
201              
202             A plugin configuration is an array of hashes. Each hash must have at least one key named "module" defined.
203              
204             =head2 PluginList
205              
206             A plugin list is a loaded set of plugin objects.
207              
208             =head1 COERCIONS
209              
210             In addition to the types above, these coercions are provided for other types.
211              
212             =head2 EmailAddress
213              
214             Coerces a C<Str> into an L<Email::Address>.
215              
216             =head2 YukkiSettings
217              
218             Coerces a C<HashRef> into this object by passing the value to the constructor.
219              
220             =head2 YukkiWebSettings
221              
222             Coerces a C<HashRef> into a L<Yukki::Web::Settings>.
223              
224             =head2 YukkiSettingsAnonymous
225              
226             Coerces a C<HashRef> into this object by passing the value to the constructor.
227              
228             =head1 AUTHOR
229              
230             Andrew Sterling Hanenkamp <hanenkamp@cpan.org>
231              
232             =head1 COPYRIGHT AND LICENSE
233              
234             This software is copyright (c) 2017 by Qubling Software LLC.
235              
236             This is free software; you can redistribute it and/or modify it under
237             the same terms as the Perl 5 programming language system itself.
238              
239             =cut