File Coverage

blib/lib/Elastic/Model/TypeMap/Moose.pm
Criterion Covered Total %
statement 30 38 78.9
branch 14 20 70.0
condition n/a
subroutine 10 13 76.9
pod n/a
total 54 71 76.0


line stmt bran cond sub pod time code
1             package Elastic::Model::TypeMap::Moose;
2             $Elastic::Model::TypeMap::Moose::VERSION = '0.51';
3 23     23   14967 use strict;
  23         50  
  23         863  
4 23     23   117 use warnings;
  23         42  
  23         748  
5              
6 23     23   117 use Elastic::Model::TypeMap::Base qw(:all);
  23         36  
  23         494  
7 23     23   159 use namespace::autoclean;
  23         40  
  23         213  
8              
9             #===================================
10             has_type 'Any',
11             #===================================
12                 deflate_via {'$val'},
13                 inflate_via {'$val'},
14                 map_via { type => 'object', enabled => 0 };
15              
16             #===================================
17             has_type 'Undef',
18             #===================================
19                 map_via { type => 'string', index => 'not_analyzed' };
20              
21             #===================================
22             has_type 'Bool',
23             #===================================
24                 map_via { type => 'boolean', null_value => 0 };
25              
26             #===================================
27             has_type 'Str',
28             #===================================
29                 map_via { type => 'string' };
30              
31             #===================================
32             has_type 'Num',
33             #===================================
34                 map_via { type => 'float' };
35              
36             #===================================
37             has_type 'Int',
38             #===================================
39                 map_via { type => 'long' };
40              
41             #===================================
42             has_type 'ScalarRef',
43             #===================================
44                 deflate_via {'$$val'},
45                 inflate_via {'\$val'},
46                 map_via { _content_handler( 'mapper', @_ ) };
47              
48             #===================================
49             has_type 'CodeRef',
50             #===================================
51                 deflate_via {undef}, inflate_via {undef};
52              
53             #===================================
54             has_type 'GlobRef',
55             #===================================
56                 deflate_via {undef}, inflate_via {undef};
57              
58             #===================================
59             has_type 'FileHandle',
60             #===================================
61                 deflate_via {undef}, inflate_via {undef};
62              
63             #===================================
64             has_type 'RegexpRef',
65             #===================================
66                 deflate_via {undef},
67                 inflate_via {undef},
68                 map_via { type => 'string', index => 'no' };
69              
70             #===================================
71             has_type 'ArrayRef',
72             #===================================
73                 deflate_via { _flate_array( 'deflator', @_ ) },
74                 inflate_via { _flate_array( 'inflator', @_ ) },
75                 map_via { _content_handler( 'mapper', @_ ) };
76              
77             #===================================
78             has_type 'HashRef',
79             #===================================
80                 deflate_via { _flate_hash( 'deflator', @_ ) },
81                 inflate_via { _flate_hash( 'inflator', @_ ) },
82                 map_via { type => 'object', enabled => 0 };
83              
84             #===================================
85             has_type 'Maybe',
86             #===================================
87                 deflate_via { _flate_maybe( 'deflator', @_ ) },
88                 inflate_via { _flate_maybe( 'inflator', @_ ) }, map_via {
89                 my $tc = $_[0];
90                 return ( type => 'boolean' )
91                     if $tc->can('type_parameter')
92                     and $tc->type_parameter->name eq 'Bool';
93                 _content_handler( 'mapper', @_ );
94                 };
95              
96             #===================================
97             has_type 'Moose::Meta::TypeConstraint::Enum',
98             #===================================
99                 deflate_via {'$val'}, #
100                 inflate_via {'$val'},
101                 map_via {
102                 type => 'string',
103                 index => 'not_analyzed',
104                 };
105              
106             #===================================
107             has_type 'Moose::Meta::TypeConstraint::Union',
108             #===================================
109                 deflate_via {undef},
110                 inflate_via {undef},
111                 map_via { type => 'object', enabled => 0 };
112              
113             #===================================
114             has_type 'MooseX::Types::TypeDecorator',
115             #===================================
116                 deflate_via { _decorated( 'deflator', @_ ) },
117                 inflate_via { _decorated( 'inflator', @_ ) },
118                 map_via { _decorated( 'mapper', @_ ) };
119              
120             #===================================
121             has_type 'Moose::Meta::TypeConstraint::Parameterized',
122             #===================================
123                 deflate_via { _parameterized( 'deflator', @_ ) },
124                 inflate_via { _parameterized( 'inflator', @_ ) },
125                 map_via { _parameterized( 'mapper', @_ ) };
126              
127             #===================================
128             sub _flate_array {
129             #===================================
130 12 100   12   28     my $content = _content_handler(@_) or return;
131                 return sub {
132 0     0   0         [ map { $content->($_) } @{ shift() } ];
  0         0  
  0         0  
133                     }
134 8 50       822         if ref $content;
135              
136 8         63     'do { [map { my $val = $_; ' . $content . '} @$val]}';
137             }
138              
139             #===================================
140             sub _flate_hash {
141             #===================================
142 12 100   12   23     my $content = _content_handler(@_) or return;
143                 return sub {
144 0     0   0         my $hash = shift;
145 0         0         +{ map { $_ => $content->( $hash->{$_} ) } keys %$hash };
  0         0  
146                     }
147 8 50       720         if ref $content;
148              
149 8         62     'do { '
150                     . 'my $hash = $val; '
151                     . '+{map { '
152                     . 'my $key = $_; my $val = $hash->{$_}; '
153                     . '$key => '
154                     . $content
155                     . '} keys %$hash}}';
156             }
157              
158             #===================================
159             sub _flate_maybe {
160             #===================================
161 12 100   12   25     my $content = _content_handler(@_) or return;
162                 return sub {
163 0 0   0   0         return defined $_[0] ? $content->( $_[0] ) : undef;
164                     }
165 8 50       475         if ref $content;
166 8         58     'defined $val ? ' . $content . ' : undef';
167             }
168              
169             #===================================
170             sub _decorated {
171             #===================================
172 157     157   313     my ( $type, $tc, $attr, $map ) = @_;
173 157         425     $map->find( $type, $tc->__type_constraint, $attr );
174             }
175              
176             #===================================
177             sub _parameterized {
178             #===================================
179 65     65   110     my ( $type, $tc, $attr, $map ) = @_;
180 65         115     my $types = $type . 's';
181 65         1802     my $parent = $tc->parent;
182 65 50       426     if ( my $handler = $map->$types->{ $parent->name } ) {
183 65         645         return $handler->( $tc, $attr, $map );
184                 }
185 0         0     $map->find( $type, $parent, $attr );
186             }
187              
188             #===================================
189             sub _content_handler {
190             #===================================
191 52     52   89     my ( $type, $tc, $attr, $map ) = @_;
192 52 100       1381     return $tc->can('type_parameter')
    100          
193                     ? $map->find( $type, $tc->type_parameter, $attr )
194                     : $type eq 'mapper' ? ( type => 'object', enabled => 0 )
195                     : '$val';
196             }
197              
198             1;
199              
200             =pod
201            
202             =encoding UTF-8
203            
204             =head1 NAME
205            
206             Elastic::Model::TypeMap::Moose - Type maps for core Moose types
207            
208             =head1 VERSION
209            
210             version 0.51
211            
212             =head1 DESCRIPTION
213            
214             L<Elastic::Model::TypeMap::Moose> provides mapping, inflation and deflation
215             for the core L<Moose::Util::TypeConstraints> and L<MooseX::Type::Moose> types.
216             It is loaded automatically by L<Elastic::Model::TypeMap::Default>.
217            
218             Definitions are inherited from parent type constraints, so a specific mapping
219             may be provided for L</Int> but the deflation and inflation is handled by
220             L</Any>.
221            
222             =head1 TYPES
223            
224             =head2 Any
225            
226             No deflation or inflation is attempted - the value is passed unaltered. If it
227             is not a value that L<JSON::XS> can handle (eg a blessed value) then
228             deflation will fail.
229            
230             It is mapped as: C<< { type => 'object', enabled => 0 } >>.
231            
232             =head2 Item
233            
234             Mapping and in/deflation via L</Any>.
235            
236             =head2 Bool
237            
238             In/deflation via L</Any>. It is mapped as:
239            
240             {
241             type => 'boolean',
242             null_value => 0
243             }
244            
245             =head2 Maybe
246            
247             An undef value is stored as a JSON C<null>. The mapping and in/deflation depend
248             on the content type, eg C<Maybe[Int]>. A C<Maybe> without a content
249             type is mapped and in/deflated via L</Any>. C<Maybe[Bool]> is special cased
250             to be mapped as:
251            
252             { type => 'boolean' }
253            
254             See L<Elastic::Manual::Attributes/BOOLEAN FIELDS> for an explanation.
255            
256             =head2 Undef
257            
258             Mapped as C<< { type => 'string', index => 'not_analyzed' } >>.
259             In/deflation via L</Any>.
260            
261             =head2 Defined
262            
263             Mapping and in/deflation via L</Any>.
264            
265             =head2 Value
266            
267             Mapping and in/deflation via L</Any>.
268            
269             =head2 Str
270            
271             Mapped as C<< { type => 'string' } >>. In/deflation via L</"Any">.
272            
273             =head2 Enum
274            
275             Values are passed through without inflation/deflation. Mapped as:
276            
277             {
278             type => 'string',
279             index => 'not_analyzed'
280             }
281            
282             =head2 Num
283            
284             Mapped as C<< { type => 'float' } >>. In/deflation via L</Any>.
285            
286             =head2 Int
287            
288             Mapped as C<< { type => 'long' } >>. In/deflation via L</"Any">.
289            
290             =head2 Ref
291            
292             No delator, inflator or mapping provided.
293            
294             =head2 ScalarRef
295            
296             The scalar value is dereferenced on deflation, and converted back
297             to a scalar ref on inflation. The mapping depends on the content type,
298             eg C<ScalarRef[Int]>. A C<ScalarRef> without a content type is mapped
299             via L</Any>.
300            
301             =head2 ArrayRef
302            
303             An array ref is preserved on inflation/deflation. The mapping depends on the
304             content type, eg C<ArrayRef[Int]>. An C<ArrayRef> without a content
305             type is mapped and in/deflated via L</Any>. For array refs with elements of
306             different types, see L<Elastic::Model::TypeMap::Structured/"Tuple">.
307            
308             =head2 HashRef
309            
310             A hash ref is preserved on inflation/deflation. It is not advisable to allow
311             arbitrary key names in indexed hashes, as you could end up generating many
312             (and conflicting) field mappings. For this reason, HashRefs are mapped
313             as C<< { type => 'object', enabled => 0 } >>. In/deflation depends on the
314             content type (eg C<HashRef[Int>]). A C<HashRef> without a content type
315             is in/deflated via L</Any>.
316            
317             If you need a hashref which is indexed, then rather use either an object or
318             L<Elastic::Model::TypeMap::Structure/"Dict">.
319            
320             =head2 Ref
321            
322             No delator, inflator or mapping provided.
323            
324             =head2 RegexpRef
325            
326             No delator or inflator is provided. It is mapped as:
327             C<< { type => 'string', index => 'no' } >>.
328            
329             =head2 GlobRef
330            
331             No delator, inflator or mapping provided.
332            
333             =head2 FileHandle
334            
335             No delator, inflator or mapping provided.
336            
337             =head1 AUTHOR
338            
339             Clinton Gormley <drtech@cpan.org>
340            
341             =head1 COPYRIGHT AND LICENSE
342            
343             This software is copyright (c) 2015 by Clinton Gormley.
344            
345             This is free software; you can redistribute it and/or modify it under
346             the same terms as the Perl 5 programming language system itself.
347            
348             =cut
349              
350             __END__
351            
352             # ABSTRACT: Type maps for core Moose types
353            
354