File Coverage

blib/lib/Telegram/Bot/Object/Base.pm
Criterion Covered Total %
statement 38 73 52.0
branch 14 38 36.8
condition 1 2 50.0
subroutine 6 7 85.7
pod 4 4 100.0
total 63 124 50.8


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