File Coverage

blib/lib/Package/JSONable.pm
Criterion Covered Total %
statement 59 60 98.3
branch 28 30 93.3
condition 7 9 77.7
subroutine 10 10 100.0
pod n/a
total 104 109 95.4


line stmt bran cond sub pod time code
1             # ABSTRACT: Add TO_JSON to your packages without the boilerplate
2             package Package::JSONable;
3             {
4             $Package::JSONable::VERSION = '0.001';
5             }
6              
7 3     3   133175 use strict;
  3         6  
  3         102  
8 3     3   18 use warnings;
  3         6  
  3         165  
9 3     3   16 use Scalar::Util qw(reftype);
  3         5  
  3         346  
10 3     3   17 use Carp qw(croak);
  3         6  
  3         139  
11 3     3   2472 use List::MoreUtils qw(none);
  3         3659  
  3         210  
12 3     3   1068 use JSON ();
  3         17461  
  3         1354  
13              
14             sub import {
15 8     8   2828 my ( $class, %import_opts ) = @_;
16              
17 8         26 my ( $target ) = caller;
18            
19             my $to_json = sub {
20 7     7   6662 my ( $self, %opts ) = @_;
21              
22 7 100       31 $self = $target unless $self;
23            
24 7 100       53 %opts = %import_opts unless %opts;
25            
26 7         29 my @types = qw/Str Int Num Bool ArrayRef HashRef/;
27              
28 7         11 my %hash;
29 7         21 foreach my $method ( keys %opts ) {
30 25         52 my $type = $opts{$method};
31 25         121 my @value = $self->$method;
32 24         99 my ( $value ) = @value;
33 24         54 my $reftype = reftype $value;
34 24         47 my $typetype = reftype $type;
35              
36 24 100       53 if ($typetype) {
37 4 100       21 croak sprintf('Invalid type: "%s"', $typetype)
38             if $typetype ne 'CODE';
39            
40 3         12 $hash{$method} = $type->($self, @value);
41 3         1022 next;
42             }
43              
44             croak sprintf('Invalid type: "%s"', $type)
45 20 100   73   121 if none { /^$type$/ } @types;
  73         417  
46            
47 19 100 100     90 if (!defined $value && $type ne 'Bool') {
48 2         5 $hash{$method} = $value;
49 2         5 next;
50             }
51              
52 17 100       75 if ( $type eq 'Str' ) {
    100          
    100          
    100          
    100          
    50          
53 3         14 $hash{$method} = $value . "";
54             }
55             elsif ( $type eq 'Int' ) {
56 2         8 $hash{$method} = int $value;
57             }
58             elsif ( $type eq 'Num' ) {
59 2         24 $hash{$method} = $value += 0;
60             }
61             elsif ( $type eq 'ArrayRef' ) {
62 4 100 66     19 if ($reftype && $reftype eq 'ARRAY') {
63 2         46 $hash{$method} = $value;
64             }
65             else {
66 2         9 $hash{$method} = [ @value ];
67             }
68             }
69             elsif ( $type eq 'HashRef' ) {
70 4 100 66     20 if ($reftype && $reftype eq 'HASH') {
71 2         8 $hash{$method} = $value;
72             }
73             else {
74 2         14 $hash{$method} = { @value };
75             }
76             }
77             elsif ( $type eq 'Bool' ) {
78 2 50       7 if ( $value ) {
79 0         0 $hash{$method} = JSON::true;
80             }
81             else {
82 2         10 $hash{$method} = JSON::false;
83             }
84             }
85             }
86              
87 4         32 return \%hash;
88 8         106 };
89            
90 3     3   75 no strict 'refs';
  3         7  
  3         204  
91 8         41 *{"${target}::TO_JSON"} = $to_json;
  8         4755  
92             }
93              
94             1;
95              
96             __END__