File Coverage

blib/lib/JSON/UnblessObject.pm
Criterion Covered Total %
statement 27 88 30.6
branch 0 26 0.0
condition 0 3 0.0
subroutine 9 18 50.0
pod 5 9 55.5
total 41 144 28.4


line stmt bran cond sub pod time code
1             package JSON::UnblessObject;
2 1     1   186381 use strict;
  1         3  
  1         23  
3 1     1   4 use warnings;
  1         2  
  1         22  
4              
5 1     1   335 use parent qw(Exporter);
  1         241  
  1         4  
6              
7             our $VERSION = "0.02";
8              
9             our @EXPORT_OK = qw(
10             unbless_object
11             );
12              
13 1     1   64 use Scalar::Util qw(blessed);
  1         1  
  1         38  
14 1     1   5 use List::Util qw(any);
  1         1  
  1         45  
15 1     1   4 use overload ();
  1         2  
  1         15  
16              
17              
18 1     1   4 use constant JSON_TYPE_ARRAYOF_CLASS => 'Cpanel::JSON::XS::Type::ArrayOf';
  1         1  
  1         58  
19 1     1   4 use constant JSON_TYPE_HASHOF_CLASS => 'Cpanel::JSON::XS::Type::HashOf';
  1         2  
  1         47  
20 1     1   5 use constant JSON_TYPE_ANYOF_CLASS => 'Cpanel::JSON::XS::Type::AnyOf';
  1         5  
  1         719  
21              
22              
23             sub unbless_object {
24 0     0 0   my ($object, $spec) = @_;
25              
26 0 0         return $object unless blessed($object);
27              
28 0 0         if (blessed $spec) {
29 0 0         return resolve_json_type_arrayof($object, $spec) if $spec->isa(JSON_TYPE_ARRAYOF_CLASS);
30 0 0         return resolve_json_type_hashof($object, $spec) if $spec->isa(JSON_TYPE_HASHOF_CLASS);
31 0 0         return resolve_json_type_anyof($object, $spec) if $spec->isa(JSON_TYPE_ANYOF_CLASS);
32              
33 0           Carp::croak sprintf("'%s' object not supported spec", $spec);
34             }
35              
36 0 0         if (my $ref = ref $spec) {
37 0 0         return resolve_arrayref($object, $spec) if $ref eq 'ARRAY';
38 0 0         return resolve_hashref($object, $spec) if $ref eq 'HASH';
39              
40 0           Carp::croak sprintf("'%s' reference not supported spec", $spec);
41             }
42              
43 0           return $object;
44             }
45              
46              
47             sub list {
48 0     0 0   my ($object) = @_;
49              
50 0 0         if (my $to_list = overload::Method($object,'@{}')) {
51 0           return $to_list->($object);
52             }
53              
54 0 0         if ($object->can('next')) {
55 0           my @list;
56 0           while (defined (my $v = $object->next)) {
57 0           push @list => $v;
58             }
59 0           return \@list;
60             }
61              
62 0           Carp::croak sprintf("'%s' object could not be converted to array ref", $object);
63             }
64              
65              
66             sub available_array {
67 0     0 0   my ($object) = @_;
68 0   0       my $f = overload::Method($object, '@{}') || $object->can('next');
69 0           return !!$f
70             }
71              
72              
73             sub available_hash {
74 0     0 0   my ($object) = @_;
75 0           my $f = $object->can('JSON_KEYS');
76 0           return !!$f;
77             }
78              
79              
80             sub resolve_arrayref {
81 0     0 1   my ($object, $spec) = @_;
82              
83 0           my @data;
84 0           my $list = list($object);
85 0           for my $i (0 .. $#$spec) {
86 0           my $v = $list->[$i];
87 0           my $s = $spec->[$i];
88 0           push @data => unbless_object($v, $s);
89             }
90 0           return \@data;
91             }
92              
93              
94             sub resolve_hashref {
95 0     0 1   my ($object, $spec) = @_;
96              
97 0           my %data;
98 0           for my $key (keys %$spec) {
99 0           my $v = $object->$key;
100 0           my $s = $spec->{$key};
101 0           $data{$key} = unbless_object($v, $s)
102             }
103 0           return \%data;
104             }
105              
106              
107             sub resolve_json_type_arrayof {
108 0     0 1   my ($object, $spec) = @_;
109              
110 0           my $s = $$spec;
111              
112 0           my @data;
113 0           my $list = list($object);
114 0           for my $v (@$list) {
115 0           push @data => unbless_object($v, $s);
116             }
117 0           return \@data;
118             }
119              
120              
121             sub resolve_json_type_hashof {
122 0     0 1   my ($object, $spec) = @_;
123              
124 0           my $s = $$spec;
125              
126 0 0         if ($object->can('JSON_KEYS')) {
127 0           my %data;
128 0           for my $key ($object->JSON_KEYS) {
129 0           my $v = $object->$key;
130 0           $data{$key} = unbless_object($v, $s)
131             }
132 0           return \%data;
133             }
134             else {
135 0           Carp::croak sprintf("'%s' object could not call JSON_KEYS method", $object);
136             }
137             }
138              
139              
140             sub resolve_json_type_anyof {
141 0     0 1   my ($object, $spec) = @_;
142              
143 0 0         my $s = available_array($object) ? $spec->[1]
    0          
144             : available_hash($object) ? $spec->[2]
145             : $spec->[0];
146              
147 0           return unbless_object($object, $s);
148             }
149              
150             1;
151             __END__