scale.rb 0.2.19 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  module Scale
2
2
  module Types
3
3
  class MetadataV6
4
- include SingleValue
4
+ include Base
5
5
  attr_accessor :call_index, :event_index
6
6
 
7
7
  def initialize(value)
@@ -11,7 +11,7 @@ module Scale
11
11
  end
12
12
 
13
13
  def self.decode(scale_bytes)
14
- modules = Scale::Types.type_of("Vec<MetadataV6Module>").decode(scale_bytes).value
14
+ modules = Scale::Types.get("Vec<MetadataV6Module>").decode(scale_bytes).value
15
15
 
16
16
  value = {
17
17
  magicNumber: 1_635_018_093,
@@ -49,7 +49,7 @@ module Scale
49
49
  end
50
50
 
51
51
  class MetadataV6Module
52
- include SingleValue
52
+ include Base
53
53
  def self.decode(scale_bytes)
54
54
  name = String.decode(scale_bytes).value
55
55
  prefix = String.decode(scale_bytes).value
@@ -61,23 +61,23 @@ module Scale
61
61
 
62
62
  has_storage = Bool.decode(scale_bytes).value
63
63
  if has_storage
64
- storages = Scale::Types.type_of("Vec<MetadataV6ModuleStorage>").decode(scale_bytes).value
64
+ storages = Scale::Types.get("Vec<MetadataV6ModuleStorage>").decode(scale_bytes).value
65
65
  result[:storage] = storages.map(&:value)
66
66
  end
67
67
 
68
68
  has_calls = Bool.decode(scale_bytes).value
69
69
  if has_calls
70
- calls = Scale::Types.type_of("Vec<MetadataModuleCall>").decode(scale_bytes).value
70
+ calls = Scale::Types.get("Vec<MetadataModuleCall>").decode(scale_bytes).value
71
71
  result[:calls] = calls.map(&:value)
72
72
  end
73
73
 
74
74
  has_events = Bool.decode(scale_bytes).value
75
75
  if has_events
76
- events = Scale::Types.type_of("Vec<MetadataModuleEvent>").decode(scale_bytes).value
76
+ events = Scale::Types.get("Vec<MetadataModuleEvent>").decode(scale_bytes).value
77
77
  result[:events] = events.map(&:value)
78
78
  end
79
79
 
80
- result[:constants] = Scale::Types.type_of("Vec<MetadataV6ModuleConstants>").decode(scale_bytes).value.map(&:value)
80
+ result[:constants] = Scale::Types.get("Vec<MetadataV6ModuleConstants>").decode(scale_bytes).value.map(&:value)
81
81
 
82
82
  MetadataV6Module.new(result)
83
83
  end
@@ -86,13 +86,13 @@ module Scale
86
86
  class MetadataV6ModuleStorage < MetadataV5ModuleStorage; end
87
87
 
88
88
  class MetadataV6ModuleConstants
89
- include SingleValue
89
+ include Base
90
90
  def self.decode(scale_bytes)
91
91
  result = {
92
92
  name: String.decode(scale_bytes).value,
93
93
  type: String.decode(scale_bytes).value, # convert
94
94
  value: Hex.decode(scale_bytes).value,
95
- documentation: Scale::Types.type_of("Vec<String>").decode(scale_bytes).value.map(&:value)
95
+ documentation: Scale::Types.get("Vec<String>").decode(scale_bytes).value.map(&:value)
96
96
  }
97
97
  MetadataV6ModuleConstants.new result
98
98
  end
@@ -1,7 +1,7 @@
1
1
  module Scale
2
2
  module Types
3
3
  class MetadataV7
4
- include SingleValue
4
+ include Base
5
5
  attr_accessor :call_index, :event_index
6
6
 
7
7
  def initialize(value)
@@ -11,7 +11,7 @@ module Scale
11
11
  end
12
12
 
13
13
  def self.decode(scale_bytes)
14
- modules = Scale::Types.type_of("Vec<MetadataV7Module>").decode(scale_bytes).value
14
+ modules = Scale::Types.get("Vec<MetadataV7Module>").decode(scale_bytes).value
15
15
 
16
16
  value = {
17
17
  magicNumber: 1_635_018_093,
@@ -49,7 +49,7 @@ module Scale
49
49
  end
50
50
 
51
51
  class MetadataV7Module
52
- include SingleValue
52
+ include Base
53
53
  def self.decode(scale_bytes)
54
54
  name = String.decode(scale_bytes).value
55
55
 
@@ -66,27 +66,27 @@ module Scale
66
66
 
67
67
  has_calls = Bool.decode(scale_bytes).value
68
68
  if has_calls
69
- calls = Scale::Types.type_of("Vec<MetadataModuleCall>").decode(scale_bytes).value
69
+ calls = Scale::Types.get("Vec<MetadataModuleCall>").decode(scale_bytes).value
70
70
  result[:calls] = calls.map(&:value)
71
71
  end
72
72
 
73
73
  has_events = Bool.decode(scale_bytes).value
74
74
  if has_events
75
- events = Scale::Types.type_of("Vec<MetadataModuleEvent>").decode(scale_bytes).value
75
+ events = Scale::Types.get("Vec<MetadataModuleEvent>").decode(scale_bytes).value
76
76
  result[:events] = events.map(&:value)
77
77
  end
78
78
 
79
- result[:constants] = Scale::Types.type_of("Vec<MetadataV7ModuleConstants>").decode(scale_bytes).value.map(&:value)
79
+ result[:constants] = Scale::Types.get("Vec<MetadataV7ModuleConstants>").decode(scale_bytes).value.map(&:value)
80
80
 
81
81
  MetadataV7Module.new(result)
82
82
  end
83
83
  end
84
84
 
85
85
  class MetadataV7ModuleStorage
86
- include SingleValue
86
+ include Base
87
87
  def self.decode(scale_bytes)
88
88
  prefix = String.decode(scale_bytes).value
89
- items = Scale::Types.type_of("Vec<MetadataV7ModuleStorageEntry>").decode(scale_bytes).value.map(&:value)
89
+ items = Scale::Types.get("Vec<MetadataV7ModuleStorageEntry>").decode(scale_bytes).value.map(&:value)
90
90
  result = {
91
91
  prefix: prefix,
92
92
  items: items
@@ -97,13 +97,24 @@ module Scale
97
97
  end
98
98
 
99
99
  class MetadataV7ModuleStorageEntry
100
- include SingleValue
100
+ include Base
101
101
  def self.decode(scale_bytes)
102
+ name = String.decode(scale_bytes).value
103
+ modifier_enum = {
104
+ "type" => "enum",
105
+ "value_list" => ["Optional", "Default"]
106
+ }
107
+ modifier = Scale::Types.get(modifier_enum).decode(scale_bytes).value
102
108
  result = {
103
- name: String.decode(scale_bytes).value,
104
- modifier: Scale::Types.type_of("Enum", %w[Optional Default]).decode(scale_bytes).value
109
+ name: name,
110
+ modifier: modifier
111
+ }
112
+
113
+ storage_function_type_enum = {
114
+ "type" => "enum",
115
+ "value_list" => %w[Plain Map DoubleMap]
105
116
  }
106
- storage_function_type = Scale::Types.type_of("Enum", %w[Plain Map DoubleMap]).decode(scale_bytes).value
117
+ storage_function_type = Scale::Types.get(storage_function_type_enum).decode(scale_bytes).value
107
118
  if storage_function_type == "Plain"
108
119
  result[:type] = {
109
120
  Plain: String.decode(scale_bytes).value
@@ -130,20 +141,20 @@ module Scale
130
141
  end
131
142
 
132
143
  result[:fallback] = Hex.decode(scale_bytes).value
133
- result[:documentation] = Scale::Types.type_of("Vec<String>").decode(scale_bytes).value.map(&:value)
144
+ result[:documentation] = Scale::Types.get("Vec<String>").decode(scale_bytes).value.map(&:value)
134
145
 
135
146
  MetadataV7ModuleStorageEntry.new(result)
136
147
  end
137
148
  end
138
149
 
139
150
  class MetadataV7ModuleConstants
140
- include SingleValue
151
+ include Base
141
152
  def self.decode(scale_bytes)
142
153
  result = {
143
154
  name: String.decode(scale_bytes).value,
144
155
  type: String.decode(scale_bytes).value, # convert
145
156
  value: Hex.decode(scale_bytes).value,
146
- documentation: Scale::Types.type_of("Vec<String>").decode(scale_bytes).value.map(&:value)
157
+ documentation: Scale::Types.get("Vec<String>").decode(scale_bytes).value.map(&:value)
147
158
  }
148
159
  MetadataV7ModuleConstants.new result
149
160
  end
@@ -1,7 +1,7 @@
1
1
  module Scale
2
2
  module Types
3
3
  class MetadataV8
4
- include SingleValue
4
+ include Base
5
5
  attr_accessor :call_index, :event_index
6
6
 
7
7
  def initialize(value)
@@ -11,7 +11,7 @@ module Scale
11
11
  end
12
12
 
13
13
  def self.decode(scale_bytes)
14
- modules = Scale::Types.type_of("Vec<MetadataV8Module>").decode(scale_bytes).value
14
+ modules = Scale::Types.get("Vec<MetadataV8Module>").decode(scale_bytes).value
15
15
 
16
16
  value = {
17
17
  magicNumber: 1_635_018_093,
@@ -49,7 +49,7 @@ module Scale
49
49
  end
50
50
 
51
51
  class MetadataV8Module
52
- include SingleValue
52
+ include Base
53
53
  def self.decode(scale_bytes)
54
54
  name = String.decode(scale_bytes).value
55
55
 
@@ -66,29 +66,29 @@ module Scale
66
66
 
67
67
  has_calls = Bool.decode(scale_bytes).value
68
68
  if has_calls
69
- calls = Scale::Types.type_of("Vec<MetadataModuleCall>").decode(scale_bytes).value
69
+ calls = Scale::Types.get("Vec<MetadataModuleCall>").decode(scale_bytes).value
70
70
  result[:calls] = calls.map(&:value)
71
71
  end
72
72
 
73
73
  has_events = Bool.decode(scale_bytes).value
74
74
  if has_events
75
- events = Scale::Types.type_of("Vec<MetadataModuleEvent>").decode(scale_bytes).value
75
+ events = Scale::Types.get("Vec<MetadataModuleEvent>").decode(scale_bytes).value
76
76
  result[:events] = events.map(&:value)
77
77
  end
78
78
 
79
- result[:constants] = Scale::Types.type_of("Vec<MetadataV7ModuleConstants>").decode(scale_bytes).value.map(&:value)
80
- result[:errors] = Scale::Types.type_of("Vec<MetadataModuleError>").decode(scale_bytes).value.map(&:value)
79
+ result[:constants] = Scale::Types.get("Vec<MetadataV7ModuleConstants>").decode(scale_bytes).value.map(&:value)
80
+ result[:errors] = Scale::Types.get("Vec<MetadataModuleError>").decode(scale_bytes).value.map(&:value)
81
81
 
82
82
  MetadataV8Module.new(result)
83
83
  end
84
84
  end
85
85
 
86
86
  class MetadataModuleError
87
- include SingleValue
87
+ include Base
88
88
  def self.decode(scale_bytes)
89
89
  result = {
90
90
  name: String.decode(scale_bytes).value,
91
- documentation: Scale::Types.type_of("Vec<String>").decode(scale_bytes).value.map(&:value)
91
+ documentation: Scale::Types.get("Vec<String>").decode(scale_bytes).value.map(&:value)
92
92
  }
93
93
 
94
94
  MetadataModuleError.new(result)
@@ -1,7 +1,7 @@
1
1
  module Scale
2
2
  module Types
3
3
  class MetadataV9
4
- include SingleValue
4
+ include Base
5
5
  attr_accessor :call_index, :event_index
6
6
 
7
7
  def initialize(value)
@@ -11,7 +11,7 @@ module Scale
11
11
  end
12
12
 
13
13
  def self.decode(scale_bytes)
14
- modules = Scale::Types.type_of("Vec<MetadataV8Module>").decode(scale_bytes).value
14
+ modules = Scale::Types.get("Vec<MetadataV8Module>").decode(scale_bytes).value
15
15
 
16
16
  value = {
17
17
  magicNumber: 1_635_018_093,
data/lib/scale.rb CHANGED
@@ -5,6 +5,11 @@ require "common"
5
5
  require "json"
6
6
  require "singleton"
7
7
 
8
+ require "scale_bytes"
9
+
10
+ require "type_registry"
11
+ require "type_builder"
12
+
8
13
  require "scale/base"
9
14
  require "scale/types"
10
15
  require "scale/block"
@@ -24,399 +29,36 @@ require "metadata/metadata_v9"
24
29
  require "metadata/metadata_v10"
25
30
  require "metadata/metadata_v11"
26
31
  require "metadata/metadata_v12"
32
+ require "metadata/metadata_v13"
27
33
 
28
34
  require "substrate_client"
29
35
  require "logger"
30
36
  require "helper"
31
37
 
32
- class String
33
- def upcase_first
34
- self.sub(/\S/, &:upcase)
35
- end
36
-
37
- def camelize2
38
- self.split('_').collect(&:upcase_first).join
39
- end
40
-
41
- def underscore2
42
- self.gsub(/::/, '/').
43
- gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
44
- gsub(/([a-z\d])([A-Z])/,'\1_\2').
45
- tr("-", "_").
46
- downcase
47
- end
48
- end
49
-
50
38
  module Scale
51
- class Error < StandardError; end
52
-
53
- class TypeRegistry
54
- include Singleton
55
-
56
- # init by load, and will not change
57
- attr_reader :spec_name, :types
58
- attr_reader :versioning, :custom_types # optional
59
-
60
- # will change by different spec version
61
- attr_accessor :spec_version # optional
62
- attr_accessor :metadata
63
-
64
- def load(spec_name: nil, custom_types: nil)
65
- @spec_name = nil
66
- @types = nil
67
- @versioning = nil
68
- @custom_types = nil
69
-
70
- default_types, _, _ = load_chain_spec_types("default")
71
-
72
- if spec_name
73
- begin
74
- @spec_name = spec_name
75
- spec_types, @versioning, @spec_version = load_chain_spec_types(spec_name)
76
- @types = default_types.merge(spec_types)
77
- rescue => ex
78
- puts "There is no types json file named #{spec_name}"
79
- @types = default_types
80
- end
81
- else
82
- @spec_name = "default"
83
- @types = default_types
84
- end
85
-
86
- self.custom_types = custom_types
87
- true
88
- end
89
-
90
- def get(type_name)
91
- raise "Types not loaded" if @types.nil?
92
-
93
- all_types = {}.merge(@types)
94
-
95
- if @spec_version && @versioning
96
- @versioning.each do |item|
97
- if @spec_version >= item["runtime_range"][0] &&
98
- ( item["runtime_range"][1].nil? || @spec_version <= item["runtime_range"][1] )
99
- all_types.merge!(item["types"])
100
- end
101
- end
102
- end
103
-
104
- all_types.merge!(@custom_types) if @custom_types
105
-
106
- type = type_traverse(type_name, all_types)
107
-
108
- Scale::Types.constantize(type)
109
- end
110
-
111
- def custom_types=(custom_types)
112
- @custom_types = custom_types.stringify_keys if (not custom_types.nil?) && custom_types.class.name == "Hash"
113
- end
114
-
115
- private
116
-
117
- def load_chain_spec_types(spec_name)
118
- file = File.join File.expand_path("../..", __FILE__), "lib", "type_registry", "#{spec_name}.json"
119
- json_string = File.open(file).read
120
- json = JSON.parse(json_string)
121
-
122
- runtime_id = json["runtime_id"]
123
-
124
- [json["types"], json["versioning"], runtime_id]
125
- end
126
-
127
- def type_traverse(type, types)
128
- type = rename(type) if type.class == ::String
129
- if types.has_key?(type) && types[type] != type
130
- type_traverse(types[type], types)
131
- else
132
- type
133
- end
134
- end
135
- end
136
-
137
- # TODO: == implement
138
-
139
- class Bytes
140
- attr_reader :data, :bytes
141
- attr_reader :offset
142
-
143
- def initialize(data)
144
- if (data.class == Array) && data.is_byte_array?
145
- @bytes = data
146
- elsif (data.class == String) && data.start_with?("0x") && (data.length % 2 == 0)
147
- arr = data[2..].scan(/../).map(&:hex)
148
- @bytes = arr
149
- else
150
- raise "Provided data is not valid"
151
- end
152
-
153
- @data = data
154
- @offset = 0
155
- end
156
-
157
- def reset_offset
158
- @offset = 0
159
- end
160
-
161
- def get_next_bytes(length)
162
- result = @bytes[@offset...@offset + length]
163
- if result.length < length
164
- str = @data[(2 + @offset * 2)..]
165
- str = str.length > 40 ? (str[0...40]).to_s + "..." : str
166
- raise "No enough data: #{str}, expect length: #{length}, but #{result.length}"
167
- end
168
- @offset += length
169
- result
170
- rescue RangeError => ex
171
- puts "length: #{length}"
172
- puts ex.message
173
- puts ex.backtrace
174
- end
175
-
176
- def get_remaining_bytes
177
- @bytes[offset..]
178
- end
179
-
180
- def to_hex_string
181
- @bytes.bytes_to_hex
182
- end
183
-
184
- def to_bin_string
185
- @bytes.bytes_to_bin
186
- end
187
-
188
- def to_ascii
189
- @bytes[0...offset].pack("C*") + "<================================>" + @bytes[offset..].pack("C*")
190
- end
191
-
192
- def ==(other)
193
- bytes == other.bytes && offset == other.offset
194
- end
195
-
196
- def to_s
197
- green(@bytes[0...offset].bytes_to_hex) + yellow(@bytes[offset..].bytes_to_hex[2..])
198
- end
199
- end
200
-
201
- class TypesLoader
202
- def self.load(filename)
203
- path = File.join File.dirname(__FILE__), "types", filename
204
- content = File.open(path).read
205
- result = JSON.parse content
206
-
207
- types = result["default"]
208
- types.each do |name, body|
209
- if body.class == String
210
- target_type = "Scale::Types::#{body}"
211
- klass = Class.new(target_type.constantize2) do
212
- end
213
- elsif body.class == Hash
214
- if body["type"] == "struct"
215
- struct_params = {}
216
- body["type_mapping"].each do |mapping|
217
- struct_params[mapping[0].to_sym] = mapping[1]
218
- end
219
- klass = Class.new do
220
- end
221
- klass.send(:include, Scale::Types::Struct)
222
- klass.send(:items, struct_params)
223
- Scale::Types.const_set name, klass
224
- elsif body["type"] = "enum"
225
- klass = Class.new do
226
- end
227
- klass.send(:include, Scale::Types::Enum)
228
- if body["type_mapping"]
229
- struct_params = {}
230
- body["type_mapping"].each do |mapping|
231
- struct_params[mapping[0].to_sym] = mapping[1]
232
- end
233
- klass.send(:items, struct_params)
234
- else
235
- klass.send(:values, body["value_list"])
236
- end
237
- Scale::Types.const_set name, klass
238
- end
239
- end
240
- end
241
- end
242
- end
39
+ class ScaleError < StandardError; end
40
+ class TypeBuildError < ScaleError; end
41
+ class BadDataError < ScaleError; end
42
+ class TypeRegistryNotLoadYet < ScaleError; end
43
+ class StorageInputTypeError < ScaleError; end
243
44
 
244
45
  module Types
245
46
  class << self
246
47
  attr_accessor :debug
247
48
  end
248
-
249
- def self.list
250
- TypeRegistry.instance.types
251
- end
252
-
253
- def self.get(type_name)
254
- type = TypeRegistry.instance.get(type_name)
255
- raise "Type '#{type_name}' not exist" if type.nil?
256
- type
257
- end
258
-
259
- def self.constantize(type)
260
- if type.class == ::String
261
- type_of(type.strip)
262
- else
263
- if type["type"] == "enum" && type.has_key?("type_mapping")
264
- type_of("Enum", type["type_mapping"].to_h)
265
- elsif type["type"] == "enum" && type.has_key?("value_list")
266
- type_of("Enum", type["value_list"])
267
- elsif type["type"] == "struct"
268
- type_of("Struct", type["type_mapping"].to_h)
269
- elsif type["type"] == "set"
270
- type_of("Set", type["value_list"])
271
- end
272
- end
273
- end
274
-
275
- def self.type_of(type_string, values = nil)
276
- if type_string.end_with?(">")
277
- type_strs = type_string.scan(/^([^<]*)<(.+)>$/).first
278
- type_str = type_strs.first
279
- inner_type_str = type_strs.last
280
-
281
- if type_str == "Vec"
282
- name = "#{type_str}<#{inner_type_str.camelize2}>"
283
- name = fix(name)
284
-
285
- if !Scale::Types.const_defined?(name)
286
- klass = Class.new do
287
- include Scale::Types::Vec
288
- inner_type inner_type_str
289
- end
290
- Scale::Types.const_set name, klass
291
- else
292
- Scale::Types.const_get name
293
- end
294
- elsif type_str == "Option"
295
- name = "#{type_str}<#{inner_type_str.camelize2}>"
296
- name = fix(name)
297
-
298
- if !Scale::Types.const_defined?(name)
299
- klass = Class.new do
300
- include Scale::Types::Option
301
- inner_type inner_type_str
302
- end
303
- Scale::Types.const_set name, klass
304
- else
305
- Scale::Types.const_get name
306
- end
307
- else
308
- raise "#{type_str} not support inner type: #{type_string}"
309
- end
310
- elsif type_string.start_with?("(") && type_string.end_with?(")") # tuple
311
- # TODO: add nested tuple support
312
- types_with_inner_type = type_string[1...-1].scan(/([A-Za-z]+<[^>]*>)/).first
313
-
314
- types_with_inner_type&.each do |type_str|
315
- new_type_str = type_str.tr(",", ";")
316
- type_string = type_string.gsub(type_str, new_type_str)
317
- end
318
49
 
319
- type_strs = type_string[1...-1].split(",").map do |type_str|
320
- type_str.strip.tr(";", ",")
321
- end
322
-
323
- name = "TupleOf#{type_strs.map(&:camelize2).join("")}"
324
- name = fix(name)
325
- if !Scale::Types.const_defined?(name)
326
- klass = Class.new do
327
- include Scale::Types::Tuple
328
- inner_types *type_strs
329
- end
330
- Scale::Types.const_set name, klass
331
- else
332
- Scale::Types.const_get name
333
- end
334
- else
335
- if type_string == "Enum"
336
- # TODO: combine values to items
337
- klass = Class.new do
338
- include Scale::Types::Enum
339
- if values.class == ::Hash
340
- items values
341
- else
342
- values(*values)
343
- end
344
- end
345
- name = values.class == ::Hash ? values.values.map(&:camelize2).join("_") : values.map(&:camelize2).join("_")
346
- name = "Enum_Of_#{name}_#{klass.object_id}"
347
- Scale::Types.const_set fix(name), klass
348
- elsif type_string == "Struct"
349
- klass = Class.new do
350
- include Scale::Types::Struct
351
- items values
352
- end
353
- name = "Struct_Of_#{values.values.map(&:camelize2).join("_")}_#{klass.object_id}"
354
- Scale::Types.const_set fix(name), klass
355
- elsif type_string == "Set"
356
- klass = Class.new do
357
- include Scale::Types::Set
358
- items values, 1
359
- end
360
- name = "Set_Of_#{values.keys.map(&:camelize2).join("_")}_#{klass.object_id}"
361
- Scale::Types.const_set fix(name), klass
362
- else
363
- type_name = (type_string.start_with?("Scale::Types::") ? type_string : "Scale::Types::#{type_string}")
364
- begin
365
- type_name.constantize2
366
- rescue NameError => e
367
- puts "#{type_string} is not defined"
368
- end
50
+ def self.check_types
51
+ TypeRegistry.instance.all_types.keys.each do |key|
52
+ begin
53
+ type = self.get(key)
54
+ rescue => ex
55
+ puts "[[ERROR]] #{key}: #{ex}"
369
56
  end
370
57
  end
58
+ true
371
59
  end
372
- end
373
-
374
- end
375
-
376
- # def fix(name)
377
- # name
378
- # .gsub("<", "˂").gsub(">", "˃")
379
- # .gsub("(", "⁽").gsub(")", "⁾")
380
- # .gsub(" ", "").gsub(",", "‚")
381
- # .gsub(":", "։")
382
- # end
383
-
384
- def fix(name)
385
- name
386
- .gsub("<", "").gsub(">", "")
387
- .gsub("(", "").gsub(")", "")
388
- .gsub(" ", "").gsub(",", "")
389
- .gsub(":", "")
390
- end
391
60
 
392
- def rename(type)
393
- type = type.gsub("T::", "")
394
- .gsub("<T>", "")
395
- .gsub("<T as Trait>::", "")
396
- .delete("\n")
397
- .gsub("EventRecord<Event, Hash>", "EventRecord")
398
- .gsub(/(u)(\d+)/, 'U\2')
399
- return "Bool" if type == "bool"
400
- return "Null" if type == "()"
401
- return "String" if type == "Vec<u8>"
402
- return "Compact" if type == "Compact<u32>" || type == "Compact<U32>"
403
- return "Address" if type == "<Lookup as StaticLookup>::Source"
404
- return "Vec<Address>" if type == "Vec<<Lookup as StaticLookup>::Source>"
405
- return "Compact" if type == "<Balance as HasCompact>::Type"
406
- return "Compact" if type == "<BlockNumber as HasCompact>::Type"
407
- return "Compact" if type == "Compact<Balance>"
408
- return "Compact" if type == "Compact<BlockNumber>"
409
- return "CompactMoment" if type == "<Moment as HasCompact>::Type"
410
- return "CompactMoment" if type == "Compact<Moment>"
411
- return "InherentOfflineReport" if type == "<InherentOfflineReport as InherentOfflineReport>::Inherent"
412
- return "AccountData" if type == "AccountData<Balance>"
413
-
414
- if type =~ /\[U\d+; \d+\]/
415
- byte_length = type.scan(/\[U\d+; (\d+)\]/).first.first.to_i
416
- return "VecU8Length#{byte_length}"
417
61
  end
418
-
419
- type
420
62
  end
421
63
 
422
64
  def green(text)
@@ -427,6 +69,24 @@ def yellow(text)
427
69
  "\033[33m#{text}\033[0m"
428
70
  end
429
71
 
72
+ class String
73
+ def upcase_first
74
+ self.sub(/\S/, &:upcase)
75
+ end
76
+
77
+ def camelize2
78
+ self.split('_').collect(&:upcase_first).join
79
+ end
80
+
81
+ def underscore2
82
+ self.gsub(/::/, '/').
83
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
84
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
85
+ tr("-", "_").
86
+ downcase
87
+ end
88
+ end
89
+
430
90
  # https://www.ruby-forum.com/t/question-about-hex-signed-int/125510/4
431
91
  # machine bit length:
432
92
  # machine_byte_length = ['foo'].pack('p').size