scale.rb 0.2.19 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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