File Coverage

blib/lib/Telegram/Bot/Object/Base.pm
Criterion Covered Total %
statement 37 71 52.1
branch 13 36 36.1
condition 1 2 50.0
subroutine 6 7 85.7
pod 4 4 100.0
total 61 120 50.8


line stmt bran cond sub pod time code
1             package Telegram::Bot::Object::Base;
2             $Telegram::Bot::Object::Base::VERSION = '0.023';
3             # ABSTRACT: The base class for all Telegram::Bot::Object objects.
4              
5              
6 5     5   3444 use Mojo::Base -base;
  5         16  
  5         46  
7              
8             has '_brain'; # a reference to our brain
9              
10              
11 56     56 1 112 sub arrays { qw// } # override if needed
12             sub _field_is_array {
13 91     91   134 my $self = shift;
14 91         115 my $field = shift;
15 91 100       223 if (grep /^$field$/, $self->arrays) {
16 1         5 return 1;
17             }
18 90         279 return;
19             }
20              
21              
22 90     90 1 180 sub array_of_arrays { qw// } #override if needed
23             sub _field_is_array_of_arrays {
24 90     90   132 my $self = shift;
25 90         124 my $field = shift;
26 90 50       173 if (grep /^$field$/, $self->array_of_arrays) {
27 0         0 return 1;
28             }
29 90         157 return;
30             }
31              
32              
33             # create an object from a hash. Needs to deal with the nested types, and
34             # arrays
35             sub create_from_hash {
36 25     25 1 1983 my $class = shift;
37 25         40 my $hash = shift;
38 25   50     56 my $brain = shift || die "no brain supplied";
39 25         99 my $obj = $class->new(_brain => $brain);
40              
41             # deal with each type of field
42 25         179 foreach my $type (keys %{ $class->fields }) {
  25         74  
43 208         339 my @fields_of_this_type = @{ $class->fields->{$type} };
  208         415  
44              
45 208         409 foreach my $field (@fields_of_this_type) {
46              
47             # ignore fields for which we have no value in the hash
48 496 100       1507 next if (! defined $hash->{$field} );
49              
50 91 100       177 if ($type eq 'scalar') {
51 76 50       151 if ($obj->_field_is_array($field)) {
    50          
52             # simple scalar array ref, so just copy it
53 0         0 my $val = $hash->{$field};
54             # deal with boolean stuff so we don't pollute our object
55             # with JSON
56 0 0       0 if (ref($val) eq 'JSON::PP::Boolean') {
57 0         0 $val = !!$val;
58             }
59 0         0 $obj->$field($val);
60             }
61             elsif ($obj->_field_is_array_of_arrays) {
62 0         0 die "not yet implemented for scalars";
63             }
64             else {
65 76         138 my $val = $hash->{$field};
66 76 50       146 if (ref($val) eq 'JSON::PP::Boolean') {
67 0         0 $val = 0+$val;
68              
69             }
70 76         205 $obj->$field($val);
71             }
72             }
73              
74             else {
75 15 100       40 if ($obj->_field_is_array($field)) {
    50          
76 1         3 my @sub_array;
77 1         1 foreach my $data ( @{ $hash->{$field} } ) {
  1         4  
78 3         14 push @sub_array, $type->create_from_hash($data, $brain);
79             }
80 1         17 $obj->$field(\@sub_array);
81             }
82             elsif ($obj->_field_is_array_of_arrays($field)) {
83 0         0 die "not yet implemented for objects";
84             }
85             else {
86 14         120 $obj->$field($type->create_from_hash($hash->{$field}, $brain));
87             }
88              
89             }
90             }
91             }
92              
93 25         202 return $obj;
94             }
95              
96              
97             sub as_hashref {
98 0     0 1   my $self = shift;
99 0           my $hash = {};
100              
101 0           foreach my $type ( keys %{ $self->fields }) {
  0            
102 0           my @fields = @{ $self->fields->{$type} };
  0            
103 0           foreach my $field (@fields) {
104              
105             # add the simple scalar values
106 0 0         if ($type eq 'scalar') {
107              
108             # TODO support scalar arrays?
109 0 0         $hash->{$field} = $self->$field
110             if defined $self->$field;
111             }
112             else {
113 0 0         if ($self->_field_is_array($field)) {
    0          
114              
115             # skip if it's not defined, though I'm not sure if there are cases
116             # where we should be sending an empty array instead?
117 0 0         next if (! defined $self->$field);
118              
119             $hash->{$field} = [
120 0           map { $_->as_hashref } @{ $self->$field }
  0            
  0            
121             ];
122             }
123             elsif ($self->_field_is_array_of_arrays($field)) {
124              
125 0 0         next if (! defined $self->$field);
126              
127             # lets not nest maps
128 0           my $a_of_a = [];
129 0           foreach my $outer ( @{ $self->$field } ) {
  0            
130 0           my $inner = [ map { $_->as_hashref } @$outer ];
  0            
131 0           push @$a_of_a, $inner;
132             }
133 0           $hash->{$field} = $a_of_a;
134             }
135             else {
136              
137             # non array, non scalar
138 0 0         if (defined $self->$field) {
139 0           my $hashref = $self->$field->as_hashref;
140 0 0         $hash->{$field} = $hashref
141             unless ! $hashref;
142             }
143             }
144             }
145             }
146             }
147 0           return $hash;
148             }
149              
150             1;
151              
152             __END__