File Coverage

blib/lib/Blockchain/Ethereum/ABI/Type/Tuple.pm
Criterion Covered Total %
statement 47 47 100.0
branch 10 12 83.3
condition 1 2 50.0
subroutine 9 9 100.0
pod 2 2 100.0
total 69 72 95.8


line stmt bran cond sub pod time code
1 6     6   89 use v5.26;
  6         21  
2 6     6   37 use Object::Pad;
  6         11  
  6         38  
3              
4             package Blockchain::Ethereum::ABI::Type::Tuple 0.012;
5             class Blockchain::Ethereum::ABI::Type::Tuple
6             :isa(Blockchain::Ethereum::ABI::Type)
7 6     6   3453 :does(Blockchain::Ethereum::ABI::TypeRole);
  6         17  
  6         156  
8              
9             =encoding utf8
10              
11             =head1 NAME
12              
13             Blockchain::Ethereum::ABI::Tuple - Interface for solidity tuple type
14              
15             =head1 SYNOPSIS
16              
17             Allows you to define and instantiate a solidity tuple type:
18              
19             my $type = Blockchain::Ethereum::ABI::Tuple->new(
20             signature => $signature,
21             data => $value
22             );
23              
24             $type->encode();
25              
26             In most cases you don't want to use this directly, use instead:
27              
28             =over 4
29              
30             =item * B: L
31              
32             =item * B: L
33              
34             =back
35              
36             =cut
37              
38 6     6   951 use Carp;
  6         16  
  6         8842  
39              
40 12     12   35 method _configure {
41              
42 12 100       43 return unless $self->data;
43              
44 8         40 my @splited_signatures = $self->_split_tuple_signature->@*;
45              
46 8         36 for (my $sig_index = 0; $sig_index < @splited_signatures; $sig_index++) {
47 29         116 push $self->_instances->@*,
48             Blockchain::Ethereum::ABI::Type->new(
49             signature => $splited_signatures[$sig_index],
50             data => $self->data->[$sig_index]);
51             }
52              
53             }
54              
55 18     18   39 method _split_tuple_signature {
56              
57             # remove the parentheses from tuple signature
58 18         50 $self->signature =~ /^\((.*)\)$/;
59 18         88 my $tuple_signatures = $1;
60              
61 18 50       47 croak "Invalid tuple signature" unless $tuple_signatures;
62              
63             # this looks through tuple signature recursively and break it into lines
64             # this is to help splitting tuples inside tuples that also contains comma
65 18         211 $tuple_signatures =~ s/((\((?>[^)(]*(?2)?)*\))|[^,()]*)(*SKIP),/$1\n/g;
66 18         74 my @types = split('\n', $tuple_signatures);
67 18         111 return \@types;
68             }
69              
70             =head2 encode
71              
72             Encodes the given data to the type of the signature
73              
74             Usage:
75              
76             encode() -> encoded string
77              
78             =over 4
79              
80             =back
81              
82             ABI encoded hex string
83              
84             =cut
85              
86 35     35 1 79 method encode {
87              
88 35 100       95 return $self->_encoded if $self->_encoded;
89              
90 22         80 my $offset = $self->_get_initial_offset;
91              
92 16         44 for my $instance ($self->_instances->@*) {
93 50         145 $instance->encode;
94 50 100       127 if ($instance->is_dynamic) {
95 14         59 $self->_push_static($self->_encode_offset($offset));
96 14         46 $self->_push_dynamic($instance->_encoded);
97 14         47 $offset += scalar $instance->_encoded->@*;
98 14         41 next;
99             }
100              
101 36         100 $self->_push_static($instance->_encoded);
102             }
103              
104 16         43 return $self->_encoded;
105             }
106              
107             =head2 decode
108              
109             Decodes the given data to the type of the signature
110              
111             Usage:
112              
113             decoded() -> array reference
114              
115             =over 4
116              
117             =back
118              
119             Array reference
120              
121             =cut
122              
123 11     11 1 20 method decode {
124              
125 11 100       27 unless (scalar $self->_instances->@* > 0) {
126 4         12 push $self->_instances->@*, Blockchain::Ethereum::ABI::Type->new(signature => $_) for $self->_split_tuple_signature->@*;
127             }
128              
129 11         56 return $self->_read_stack_set_data;
130             }
131              
132 6     6   13 method _static_size :override {
133              
134 6 50       13 return 1 if $self->is_dynamic;
135              
136 6         12 my $size = 1;
137 6         10 my $instance_size = 0;
138 6         14 for my $signature ($self->_split_tuple_signature->@*) {
139 12         59 my $instance = Blockchain::Ethereum::ABI::Type->new(signature => $signature);
140 12   50     35 $instance_size += $instance->_static_size // 0;
141             }
142              
143 6         19 return $size * $instance_size;
144             }
145              
146             1;
147              
148             __END__