File Coverage

blib/lib/Blockchain/Contract/Solidity/ABI/Type/Tuple.pm
Criterion Covered Total %
statement 51 51 100.0
branch 9 10 90.0
condition 1 2 50.0
subroutine 11 11 100.0
pod 0 5 0.0
total 72 79 91.1


line stmt bran cond sub pod time code
1             package Blockchain::Contract::Solidity::ABI::Type::Tuple;
2              
3 5     5   61 use v5.26;
  5         19  
4 5     5   29 use strict;
  5         12  
  5         102  
5 5     5   25 use warnings;
  5         10  
  5         128  
6 5     5   25 no indirect;
  5         11  
  5         38  
7              
8 5     5   260 use Carp;
  5         11  
  5         302  
9 5     5   451 use parent qw(Blockchain::Contract::Solidity::ABI::Type);
  5         321  
  5         27  
10              
11             sub configure {
12 33     33 0 71 my $self = shift;
13 33 100       107 return unless $self->data;
14              
15 8         27 my @splited_signatures = $self->split_tuple_signature->@*;
16              
17 8         33 for (my $sig_index = 0; $sig_index < @splited_signatures; $sig_index++) {
18 29         97 push $self->instances->@*,
19             Blockchain::Contract::Solidity::ABI::Type::new_type(
20             signature => $splited_signatures[$sig_index],
21             data => $self->data->[$sig_index]);
22             }
23              
24             }
25              
26             sub split_tuple_signature {
27 18     18 0 37 my $self = shift;
28 18         50 my $tuple_signatures = substr($self->signature, 1, length($self->signature) - 2);
29 18         235 $tuple_signatures =~ s/((\((?>[^)(]*(?2)?)*\))|[^,()]*)(*SKIP),/$1\n/g;
30 18         78 my @types = split('\n', $tuple_signatures);
31 18         71 return \@types;
32             }
33              
34             sub encode {
35 35     35 0 64 my $self = shift;
36 35 100       117 return $self->encoded if $self->encoded;
37              
38 22         82 my $offset = $self->get_initial_offset;
39              
40 16         51 for my $instance ($self->instances->@*) {
41 50         160 $instance->encode;
42 50 100       136 if ($instance->is_dynamic) {
43 14         61 $self->push_static($self->encode_offset($offset));
44 14         44 $self->push_dynamic($instance->encoded);
45 14         43 $offset += scalar $instance->encoded->@*;
46 14         38 next;
47             }
48              
49 36         120 $self->push_static($instance->encoded);
50             }
51              
52 16         40 return $self->encoded;
53             }
54              
55             sub decode {
56 11     11 0 20 my $self = shift;
57              
58 11 100       29 unless (scalar $self->instances->@* > 0) {
59 4         33 push $self->instances->@*, Blockchain::Contract::Solidity::ABI::Type::new_type(signature => $_) for $self->split_tuple_signature->@*;
60             }
61              
62 11         40 return $self->read_stack_set_data;
63             }
64              
65             sub static_size {
66 6     6 0 13 my $self = shift;
67 6 50       15 return 1 if $self->is_dynamic;
68 6         17 my $size = 1;
69 6         15 my $instance_size = 0;
70 6         16 for my $signature ($self->split_tuple_signature->@*) {
71 12         27 my $instance = Blockchain::Contract::Solidity::ABI::Type::new_type(signature => $signature);
72 12   50     44 $instance_size += $instance->static_size // 0;
73             }
74              
75 6         23 return $size * $instance_size;
76             }
77              
78             1;
79