File Coverage

blib/lib/Types/JsonCoercions.pm
Criterion Covered Total %
statement 19 19 100.0
branch n/a
condition 2 2 100.0
subroutine 7 7 100.0
pod n/a
total 28 28 100.0


line stmt bran cond sub pod time code
1 1     1   157606 use 5.008009;
  1         4  
2 1     1   5 use strict;
  1         2  
  1         25  
3 1     1   5 use warnings;
  1         2  
  1         90  
4              
5             package Types::JsonCoercions;
6              
7             our $AUTHORITY = 'cpan:TOBYINK';
8             our $VERSION = '0.001';
9              
10             use Type::Library 1.004
11 1         7 -base,
12 1     1   6 -declare => qw( ArrayRefJ HashRefJ RefJ StrJ );
  1         21  
13 1     1   754 use Types::Standard 1.004 qw( Str Ref ArrayRef HashRef );
  1         15  
  1         7  
14              
15             our $JSON;
16              
17             sub _code_to_load_package {
18 4     4   9 my ( $me, $pkg, $keyword ) = ( shift, @_ );
19 4   100     14 $keyword ||= 'do';
20 4         34 return sprintf(
21             '%s { require %s; q[%s] }',
22             $keyword,
23             $pkg,
24             $pkg,
25             );
26             }
27              
28             sub _code_for_json_encoder {
29 2     2   19 my ( $me ) = ( shift );
30 2         6 return sprintf(
31             '$%s::JSON ||= ( %s or %s )->new',
32             $me,
33             $me->_code_to_load_package( 'JSON::MaybeXS', 'eval' ),
34             $me->_code_to_load_package( 'JSON::PP' ),
35             );
36             }
37              
38             my $meta = __PACKAGE__->meta;
39              
40             my $ToJson = $meta->add_coercion( {
41             name => 'ToJSON',
42             frozen => 1,
43             type_coercion_map => [
44             Ref, sprintf( q{ ( %s )->encode( $_ ) }, __PACKAGE__->_code_for_json_encoder ),
45             ],
46             } );
47              
48             my $FromJson = $meta->add_coercion( {
49             name => 'FromJSON',
50             frozen => 1,
51             type_coercion_map => [
52             Str, sprintf( q{ ( %s )->decode( $_ ) }, __PACKAGE__->_code_for_json_encoder ),
53             ],
54             } );
55              
56             $meta->add_type( {
57             name => StrJ,
58             parent => Str->plus_coercions( $ToJson ),
59             coercion => 1,
60             } );
61              
62             $meta->add_type( {
63             name => RefJ,
64             parent => Ref->plus_coercions( $FromJson ),
65             coercion => 1,
66             constraint_generator => sub {
67             Ref->of( @_ )->plus_coercions( $FromJson );
68             },
69             } );
70              
71             $meta->add_type( {
72             name => HashRefJ,
73             parent => HashRef->plus_coercions( $FromJson ),
74             coercion => 1,
75             constraint_generator => sub {
76             HashRef->of( @_ )->plus_coercions( $FromJson );
77             },
78             } );
79              
80             $meta->add_type( {
81             name => ArrayRefJ,
82             parent => ArrayRef->plus_coercions( $FromJson ),
83             coercion => 1,
84             constraint_generator => sub {
85             ArrayRef->of( @_ )->plus_coercions( $FromJson );
86             },
87             } );
88              
89             1;
90              
91             __END__