scale.rb 0.1.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.
- checksums.yaml +7 -0
- data/.DS_Store +0 -0
- data/.gitignore +10 -0
- data/Dockerfile +18 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +49 -0
- data/LICENSE.txt +21 -0
- data/README.md +149 -0
- data/Rakefile +2 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/grants_badge.png +0 -0
- data/lib/metadata/metadata.rb +127 -0
- data/lib/metadata/metadata_v10.rb +22 -0
- data/lib/metadata/metadata_v3.rb +22 -0
- data/lib/metadata/metadata_v7.rb +123 -0
- data/lib/metadata/metadata_v8.rb +69 -0
- data/lib/metadata/metadata_v9.rb +22 -0
- data/lib/scale/base.rb +322 -0
- data/lib/scale/types.rb +561 -0
- data/lib/scale/version.rb +3 -0
- data/lib/scale.rb +187 -0
- data/scale.gemspec +43 -0
- metadata +137 -0
data/lib/scale.rb
ADDED
@@ -0,0 +1,187 @@
|
|
1
|
+
require "scale/version"
|
2
|
+
|
3
|
+
require "substrate_common"
|
4
|
+
|
5
|
+
require "scale/base"
|
6
|
+
require "scale/types"
|
7
|
+
|
8
|
+
require "metadata/metadata"
|
9
|
+
require "metadata/metadata_v3"
|
10
|
+
require "metadata/metadata_v7"
|
11
|
+
require "metadata/metadata_v8"
|
12
|
+
require "metadata/metadata_v9"
|
13
|
+
require "metadata/metadata_v10"
|
14
|
+
|
15
|
+
module Scale
|
16
|
+
class Error < StandardError; end
|
17
|
+
# TODO: == implement
|
18
|
+
|
19
|
+
class Bytes
|
20
|
+
attr_reader :data, :bytes
|
21
|
+
attr_reader :offset
|
22
|
+
|
23
|
+
def initialize(data)
|
24
|
+
if data.class == Array and data.is_byte_array?
|
25
|
+
@bytes = data
|
26
|
+
elsif data.class == String and data.start_with?('0x') and data.length % 2 == 0
|
27
|
+
arr = data[2..].scan(/../).map(&:hex)
|
28
|
+
@bytes = arr
|
29
|
+
else
|
30
|
+
raise "Provided data is not valid"
|
31
|
+
end
|
32
|
+
|
33
|
+
@data = data
|
34
|
+
@offset = 0
|
35
|
+
end
|
36
|
+
|
37
|
+
def reset_offset
|
38
|
+
@offset = 0
|
39
|
+
end
|
40
|
+
|
41
|
+
def get_next_bytes(length)
|
42
|
+
result = @bytes[@offset ... @offset + length]
|
43
|
+
if result.length < length
|
44
|
+
str = @data[(2 + @offset * 2)..]
|
45
|
+
str = str.length > 40 ? (str[0...40]).to_s + "..." : str
|
46
|
+
raise "No enough data: #{str}, expect length: #{length}, but #{result.length}"
|
47
|
+
end
|
48
|
+
@offset = @offset + length
|
49
|
+
result
|
50
|
+
end
|
51
|
+
|
52
|
+
def get_remaining_bytes
|
53
|
+
@bytes[offset..]
|
54
|
+
@offset = @bytes.length
|
55
|
+
result
|
56
|
+
end
|
57
|
+
|
58
|
+
def to_hex_string
|
59
|
+
@bytes.bytes_to_hex
|
60
|
+
end
|
61
|
+
|
62
|
+
def to_bin_string
|
63
|
+
@bytes.bytes_to_bin
|
64
|
+
end
|
65
|
+
|
66
|
+
def ==(another_object)
|
67
|
+
self.bytes == another_object.bytes && self.offset == another_object.offset
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
class TypesLoader
|
72
|
+
def self.load(filename)
|
73
|
+
path = File.join File.dirname(__FILE__), "types", filename
|
74
|
+
content = File.open(path).read
|
75
|
+
result = JSON.parse content
|
76
|
+
|
77
|
+
types = result["default"]
|
78
|
+
types.each do |name, body|
|
79
|
+
if body.class == String
|
80
|
+
target_type = "Scale::Types::#{body}"
|
81
|
+
klass = Class.new(target_type.constantize) do
|
82
|
+
end
|
83
|
+
elsif body.class == Hash
|
84
|
+
if body["type"] == "struct"
|
85
|
+
struct_params = {}
|
86
|
+
body['type_mapping'].each do |mapping|
|
87
|
+
struct_params[mapping[0].to_sym] = mapping[1]
|
88
|
+
end
|
89
|
+
klass = Class.new do
|
90
|
+
end
|
91
|
+
klass.send(:include, Scale::Types::Struct)
|
92
|
+
klass.send(:items, struct_params)
|
93
|
+
Scale::Types.const_set name, klass
|
94
|
+
elsif body["type"] = "enum"
|
95
|
+
klass = Class.new do
|
96
|
+
end
|
97
|
+
klass.send(:include, Scale::Types::Enum)
|
98
|
+
if body["type_mapping"]
|
99
|
+
struct_params = {}
|
100
|
+
body['type_mapping'].each do |mapping|
|
101
|
+
struct_params[mapping[0].to_sym] = mapping[1]
|
102
|
+
end
|
103
|
+
klass.send(:items, struct_params)
|
104
|
+
else
|
105
|
+
klass.send(:values, body["value_list"])
|
106
|
+
end
|
107
|
+
Scale::Types.const_set name, klass
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
def type_of(type_string, enum_values: nil)
|
117
|
+
if type_string.end_with?(">")
|
118
|
+
type_strs = type_string.scan(/^([^<]*)<(.+)>$/).first
|
119
|
+
type_str = type_strs.first
|
120
|
+
inner_type_str = type_strs.last
|
121
|
+
|
122
|
+
if type_str == "Vec" || type_str == "Option"
|
123
|
+
klass = Class.new do
|
124
|
+
include type_of(type_str)
|
125
|
+
inner_type inner_type_str
|
126
|
+
end
|
127
|
+
name = "#{type_str}#{klass.object_id}"
|
128
|
+
Object.const_set name, klass
|
129
|
+
return name.constantize
|
130
|
+
else
|
131
|
+
raise "#{type_str} not support inner type"
|
132
|
+
end
|
133
|
+
elsif type_string.start_with?("(") && type_string.end_with?(")") # tuple
|
134
|
+
# TODO: add nested tuple support
|
135
|
+
types_with_inner_type = type_string[1...-1].scan(/([A-Za-z]+<[^>]*>)/).first
|
136
|
+
|
137
|
+
if not types_with_inner_type.nil?
|
138
|
+
types_with_inner_type.each do |type_str|
|
139
|
+
new_type_str = type_str.gsub(",", ";")
|
140
|
+
type_string = type_string.gsub(type_str, new_type_str)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
type_strs = type_string[1...-1].split(",").map do |type_str|
|
145
|
+
type_str.strip.gsub(";", ",")
|
146
|
+
end
|
147
|
+
|
148
|
+
klass = Class.new do
|
149
|
+
include Scale::Types::Tuple
|
150
|
+
inner_types *type_strs
|
151
|
+
end
|
152
|
+
name = "Tuple#{klass.object_id}"
|
153
|
+
Object.const_set name, klass
|
154
|
+
return name.constantize
|
155
|
+
else
|
156
|
+
if type_string == 'Enum'
|
157
|
+
klass = Class.new do
|
158
|
+
include Scale::Types::Enum
|
159
|
+
values *enum_values
|
160
|
+
end
|
161
|
+
name = "Enum#{klass.object_id}"
|
162
|
+
Object.const_set name, klass
|
163
|
+
return name.constantize
|
164
|
+
else
|
165
|
+
type_string = (type_string.start_with?("Scale::Types::") ? type_string : "Scale::Types::#{type_string}")
|
166
|
+
type_string.constantize
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def adjust(type)
|
172
|
+
type = type.gsub("T::", "")
|
173
|
+
.gsub("<T>", "")
|
174
|
+
.gsub("<T as Trait>::", "")
|
175
|
+
.gsub("\n", "")
|
176
|
+
.gsub("EventRecord<Event, Hash>", "EventRecord")
|
177
|
+
return "Null" if type == "()"
|
178
|
+
return "String" if type == "Vec<u8>"
|
179
|
+
return "Address" if type == '<Lookup as StaticLookup>::Source'
|
180
|
+
return "Vec<Address>" if type == 'Vec<<Lookup as StaticLookup>::Source>'
|
181
|
+
return "CompactBalance" if type == '<Balance as HasCompact>::Type'
|
182
|
+
return 'CompactBlockNumber' if type == '<BlockNumber as HasCompact>::Type'
|
183
|
+
return 'CompactBalance' if type == '<Balance as HasCompact>::Type'
|
184
|
+
return 'CompactMoment' if type == '<Moment as HasCompact>::Type'
|
185
|
+
return 'InherentOfflineReport' if type == '<InherentOfflineReport as InherentOfflineReport>::Inherent'
|
186
|
+
return type
|
187
|
+
end
|
data/scale.gemspec
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "scale/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "scale.rb"
|
8
|
+
spec.version = Scale::VERSION
|
9
|
+
spec.authors = ["Wu Minzhe"]
|
10
|
+
spec.email = ["wuminzhe@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{Ruby implementation of the parity SCALE data format}
|
13
|
+
spec.description = %q{SCALE - Simple Concatenating Aggregated Little Endians}
|
14
|
+
spec.homepage = "https://github.com/itering/scale.rb"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
18
|
+
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
19
|
+
if spec.respond_to?(:metadata)
|
20
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
21
|
+
|
22
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
23
|
+
else
|
24
|
+
raise "RubyGems 2.0 or newer is required to protect against " \
|
25
|
+
"public gem pushes."
|
26
|
+
end
|
27
|
+
|
28
|
+
# Specify which files should be added to the gem when it is released.
|
29
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
30
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
31
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
32
|
+
end
|
33
|
+
spec.bindir = "exe"
|
34
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
35
|
+
spec.require_paths = ["lib"]
|
36
|
+
|
37
|
+
spec.add_dependency "substrate_common.rb", "~> 0.1.3"
|
38
|
+
|
39
|
+
spec.add_development_dependency "bundler", "~> 1.17"
|
40
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
41
|
+
spec.add_development_dependency "rspec", "~> 3.2"
|
42
|
+
spec.add_development_dependency "pry"
|
43
|
+
end
|
metadata
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: scale.rb
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Wu Minzhe
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-03-11 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: substrate_common.rb
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.1.3
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.1.3
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.17'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.17'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '13.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '13.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.2'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.2'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pry
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: SCALE - Simple Concatenating Aggregated Little Endians
|
84
|
+
email:
|
85
|
+
- wuminzhe@gmail.com
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- ".DS_Store"
|
91
|
+
- ".gitignore"
|
92
|
+
- Dockerfile
|
93
|
+
- Gemfile
|
94
|
+
- Gemfile.lock
|
95
|
+
- LICENSE.txt
|
96
|
+
- README.md
|
97
|
+
- Rakefile
|
98
|
+
- bin/console
|
99
|
+
- bin/setup
|
100
|
+
- grants_badge.png
|
101
|
+
- lib/metadata/metadata.rb
|
102
|
+
- lib/metadata/metadata_v10.rb
|
103
|
+
- lib/metadata/metadata_v3.rb
|
104
|
+
- lib/metadata/metadata_v7.rb
|
105
|
+
- lib/metadata/metadata_v8.rb
|
106
|
+
- lib/metadata/metadata_v9.rb
|
107
|
+
- lib/scale.rb
|
108
|
+
- lib/scale/base.rb
|
109
|
+
- lib/scale/types.rb
|
110
|
+
- lib/scale/version.rb
|
111
|
+
- scale.gemspec
|
112
|
+
homepage: https://github.com/itering/scale.rb
|
113
|
+
licenses:
|
114
|
+
- MIT
|
115
|
+
metadata:
|
116
|
+
allowed_push_host: https://rubygems.org
|
117
|
+
homepage_uri: https://github.com/itering/scale.rb
|
118
|
+
post_install_message:
|
119
|
+
rdoc_options: []
|
120
|
+
require_paths:
|
121
|
+
- lib
|
122
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
123
|
+
requirements:
|
124
|
+
- - ">="
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: '0'
|
127
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
requirements: []
|
133
|
+
rubygems_version: 3.0.6
|
134
|
+
signing_key:
|
135
|
+
specification_version: 4
|
136
|
+
summary: Ruby implementation of the parity SCALE data format
|
137
|
+
test_files: []
|