scale_rb 0.4.1 → 0.5.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 +4 -4
- data/.devcontainer/devcontainer.json +21 -0
- data/Dockerfile +16 -0
- data/Gemfile +4 -4
- data/README.md +19 -6
- data/bin/console +0 -0
- data/bin/setup +0 -0
- data/examples/http_client_1.rb +0 -2
- data/examples/http_client_2.rb +0 -2
- data/examples/ws_client_1.rb +0 -2
- data/examples/ws_client_3.rb +1 -3
- data/examples/ws_client_4.rb +0 -2
- data/exe/metadata +9 -11
- data/lib/address.rb +1 -1
- data/lib/custom_assign.rb +92 -0
- data/lib/scale_rb/call_helper.rb +42 -0
- data/lib/{client → scale_rb/client}/client_ext.rb +12 -13
- data/lib/{client → scale_rb/client}/http_client.rb +3 -5
- data/lib/{client → scale_rb/client}/ws_client.rb +13 -20
- data/lib/scale_rb/codec.rb +25 -0
- data/lib/scale_rb/codec_utils.rb +128 -0
- data/lib/scale_rb/decode.rb +164 -0
- data/lib/scale_rb/encode.rb +150 -0
- data/lib/{hasher.rb → scale_rb/hasher.rb} +10 -8
- data/lib/scale_rb/metadata/metadata.rb +114 -0
- data/lib/{metadata → scale_rb/metadata}/metadata_v10.rb +0 -17
- data/lib/{metadata → scale_rb/metadata}/metadata_v11.rb +0 -17
- data/lib/{metadata → scale_rb/metadata}/metadata_v12.rb +0 -17
- data/lib/{metadata → scale_rb/metadata}/metadata_v13.rb +0 -17
- data/lib/{metadata → scale_rb/metadata}/metadata_v14.rb +18 -18
- data/lib/{metadata → scale_rb/metadata}/metadata_v9.rb +0 -17
- data/lib/scale_rb/metadata/registry.rb +263 -0
- data/lib/scale_rb/metadata/type_exp.rb +286 -0
- data/lib/scale_rb/portable_registry.rb +133 -0
- data/lib/{storage_helper.rb → scale_rb/storage_helper.rb} +16 -4
- data/lib/scale_rb/types.rb +233 -0
- data/lib/scale_rb/utils.rb +125 -0
- data/lib/scale_rb/version.rb +1 -1
- data/lib/scale_rb.rb +22 -30
- data/lib/type_enforcer.rb +170 -0
- data/scale_rb.gemspec +5 -0
- metadata +71 -19
- data/lib/codec.rb +0 -450
- data/lib/metadata/metadata.rb +0 -137
- data/lib/monkey_patching.rb +0 -115
- data/lib/portable_codec.rb +0 -285
- data/lib/registry.rb +0 -13
@@ -0,0 +1,170 @@
|
|
1
|
+
require_relative 'custom_assign'
|
2
|
+
require 'benchmark'
|
3
|
+
|
4
|
+
# rubocop:disable all
|
5
|
+
module TypeEnforcer
|
6
|
+
|
7
|
+
def self.extended(base)
|
8
|
+
base.instance_variable_set(:@type_enforcements, {})
|
9
|
+
base.instance_variable_set(:@applying_enforcement, false)
|
10
|
+
end
|
11
|
+
|
12
|
+
def __(method_name, param_types, return_type = nil, level: 1, skip: [])
|
13
|
+
return unless type_enforcement_enabled?
|
14
|
+
|
15
|
+
@type_enforcements[method_name] = {
|
16
|
+
params: param_types,
|
17
|
+
return: return_type,
|
18
|
+
level: level,
|
19
|
+
skip: skip
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
def method_added(method_name)
|
24
|
+
super
|
25
|
+
apply_enforcement(method_name)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def apply_enforcement(method_name)
|
31
|
+
return unless type_enforcement_enabled?
|
32
|
+
return if @applying_enforcement
|
33
|
+
return unless @type_enforcements.key?(method_name)
|
34
|
+
|
35
|
+
@applying_enforcement = true
|
36
|
+
begin
|
37
|
+
result = @type_enforcements[method_name]
|
38
|
+
if result[:level] > type_enforcement_level
|
39
|
+
decorate(method_name, result[:params], result[:return], result[:skip])
|
40
|
+
end
|
41
|
+
ensure
|
42
|
+
@applying_enforcement = false
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def type_enforcement_enabled?
|
47
|
+
return true if ENV['ENABLE_TYPE_ENFORCEMENT'] && ENV['ENABLE_TYPE_ENFORCEMENT'] == 'true'
|
48
|
+
|
49
|
+
false
|
50
|
+
end
|
51
|
+
|
52
|
+
def type_enforcement_level
|
53
|
+
ENV['TYPE_ENFORCEMENT_LEVEL'].to_i || 2
|
54
|
+
end
|
55
|
+
|
56
|
+
def decorate(method_name, param_types, return_type, skip)
|
57
|
+
target = self
|
58
|
+
original_method = target.instance_method(method_name)
|
59
|
+
method_parameters = original_method.parameters
|
60
|
+
|
61
|
+
# only support positional args and keyword args for now
|
62
|
+
# TODO: support splat(rest), double splat(keyrest) args, and block
|
63
|
+
target.define_method(method_name) do |*args, **kwargs|
|
64
|
+
ScaleRb.logger.debug("----------------------------------------------------------")
|
65
|
+
ScaleRb.logger.debug("method: #{method_name}")
|
66
|
+
ScaleRb.logger.debug("params: args: #{args}, kwargs: #{kwargs}")
|
67
|
+
ScaleRb.logger.debug("param kinds: #{method_parameters}")
|
68
|
+
ScaleRb.logger.debug("param types: #{param_types}")
|
69
|
+
|
70
|
+
validated_args = []
|
71
|
+
validated_kwargs = {}
|
72
|
+
|
73
|
+
# build a hash of param_name => value | default_value
|
74
|
+
defaults = method_parameters.each_with_object({}) do |(_param_kind, param_name), memo|
|
75
|
+
type = param_types[param_name]
|
76
|
+
memo[param_name] = type.value if type.respond_to?(:value)
|
77
|
+
end
|
78
|
+
assigned_params = build_assigned_params(original_method, defaults, args, kwargs)
|
79
|
+
ScaleRb.logger.debug("assigned params: #{assigned_params}")
|
80
|
+
|
81
|
+
# validate each param
|
82
|
+
method_parameters.each do |param_kind, param_name|
|
83
|
+
case param_kind
|
84
|
+
when :req, :opt
|
85
|
+
value = assigned_params[param_name]
|
86
|
+
if skip.include?(param_name)
|
87
|
+
validated_args << value
|
88
|
+
else
|
89
|
+
type = param_types[param_name]
|
90
|
+
validated_args << type[value]
|
91
|
+
end
|
92
|
+
when :keyreq, :key
|
93
|
+
value = assigned_params[param_name]
|
94
|
+
if skip.include?(param_name)
|
95
|
+
validated_kwargs[param_name] = value
|
96
|
+
else
|
97
|
+
type = param_types[param_name]
|
98
|
+
validated_kwargs[param_name] = type[value]
|
99
|
+
end
|
100
|
+
when :rest, :keyrest
|
101
|
+
raise NotImplementedError, 'rest and keyrest args not supported'
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
result = original_method.bind(self).call(*validated_args, **validated_kwargs)
|
106
|
+
|
107
|
+
if skip.include?(:returns) && return_type
|
108
|
+
return_type[result]
|
109
|
+
else
|
110
|
+
result
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# require 'dry-types'
|
117
|
+
|
118
|
+
# module Types
|
119
|
+
# include Dry.Types()
|
120
|
+
# end
|
121
|
+
|
122
|
+
# class Example
|
123
|
+
# extend TypeEnforcer
|
124
|
+
|
125
|
+
# __ :add, { a: Types::Strict::Integer, b: Types::Strict::Integer }, Types::Strict::Integer
|
126
|
+
# def self.add(a, b)
|
127
|
+
# a + b
|
128
|
+
# end
|
129
|
+
|
130
|
+
# __ :subtract, { a: Types::Strict::Integer, b: Types::Strict::Integer }, Types::Strict::Integer
|
131
|
+
# def subtract(a, b)
|
132
|
+
# a - b
|
133
|
+
# end
|
134
|
+
|
135
|
+
# __ :my_method, {
|
136
|
+
# a: Types::Strict::Integer,
|
137
|
+
# b: Types::Strict::Integer.default(2),
|
138
|
+
# c: Types::Strict::Integer,
|
139
|
+
# d: Types::Strict::Integer.default(4)
|
140
|
+
# }, Types::Strict::String
|
141
|
+
# def my_method(a, b = 2, c:, d: 4)
|
142
|
+
# "a: #{a}, b: #{b}, c: #{c}, d: #{d}"
|
143
|
+
# end
|
144
|
+
# end
|
145
|
+
|
146
|
+
# puts Example.add(1, 2) # => 3
|
147
|
+
|
148
|
+
# puts Example.new.subtract(3, 1) # => 2
|
149
|
+
|
150
|
+
# begin
|
151
|
+
# puts Example.new.subtract(3, '1')
|
152
|
+
# rescue StandardError => e
|
153
|
+
# puts e.class # => Dry::Types::ConstraintError
|
154
|
+
# puts e.message # => "1" violates constraints (type?(Integer, "1") failed)
|
155
|
+
# end
|
156
|
+
|
157
|
+
# puts Example.new.my_method(5, c: 3) # => "a: 5, b: 2, c: 3, d: 4"
|
158
|
+
# puts Example.new.my_method(5, 6, c: 3) # => "a: 5, b: 6, c: 3, d: 4"
|
159
|
+
# puts Example.new.my_method(5, 6, c: 3, d: 10) # => "a: 5, b: 6, c: 3, d: 10"
|
160
|
+
# begin
|
161
|
+
# puts Example.new.my_method(5, 6, c: 3, d: '10')
|
162
|
+
# rescue StandardError => e
|
163
|
+
# puts e.class # => Dry::Types::ConstraintError
|
164
|
+
# puts e.message # => "10" violates constraints (type?(Integer, "10") failed)
|
165
|
+
# end
|
166
|
+
# begin
|
167
|
+
# puts Example.new.my_method(5, 6, d: 10)
|
168
|
+
# rescue StandardError => e
|
169
|
+
# puts e.message # => Missing required keyword argument: c
|
170
|
+
# end
|
data/scale_rb.gemspec
CHANGED
@@ -38,4 +38,9 @@ Gem::Specification.new do |spec|
|
|
38
38
|
spec.add_dependency 'async'
|
39
39
|
spec.add_dependency 'async-http', '~> 0.69.0'
|
40
40
|
spec.add_dependency 'async-websocket', '~> 0.26.2'
|
41
|
+
# for logger
|
42
|
+
spec.add_dependency 'console'
|
43
|
+
# for types restriction
|
44
|
+
spec.add_dependency 'dry-struct'
|
45
|
+
spec.add_dependency 'dry-types'
|
41
46
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: scale_rb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aki Wu
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-10-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: base58
|
@@ -94,6 +94,48 @@ dependencies:
|
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: 0.26.2
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: console
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: dry-struct
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: dry-types
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
97
139
|
description: This gem includes a ruby implementation of SCALE Codec, a general Substrate
|
98
140
|
Http JSONRPC Client, and, a general Substrate Websocket JSON-RPC Client.
|
99
141
|
email:
|
@@ -103,11 +145,13 @@ executables:
|
|
103
145
|
extensions: []
|
104
146
|
extra_rdoc_files: []
|
105
147
|
files:
|
148
|
+
- ".devcontainer/devcontainer.json"
|
106
149
|
- ".gitignore"
|
107
150
|
- ".rspec"
|
108
151
|
- ".rubocop.yml"
|
109
152
|
- ".travis.yml"
|
110
153
|
- CODE_OF_CONDUCT.md
|
154
|
+
- Dockerfile
|
111
155
|
- Gemfile
|
112
156
|
- LICENSE.txt
|
113
157
|
- README.md
|
@@ -123,24 +167,32 @@ files:
|
|
123
167
|
- examples/ws_client_error_handling.rb
|
124
168
|
- exe/metadata
|
125
169
|
- lib/address.rb
|
126
|
-
- lib/
|
127
|
-
- lib/client/http_client.rb
|
128
|
-
- lib/client/ws_client.rb
|
129
|
-
- lib/codec.rb
|
130
|
-
- lib/hasher.rb
|
131
|
-
- lib/metadata/metadata.rb
|
132
|
-
- lib/metadata/metadata_v10.rb
|
133
|
-
- lib/metadata/metadata_v11.rb
|
134
|
-
- lib/metadata/metadata_v12.rb
|
135
|
-
- lib/metadata/metadata_v13.rb
|
136
|
-
- lib/metadata/metadata_v14.rb
|
137
|
-
- lib/metadata/metadata_v9.rb
|
138
|
-
- lib/monkey_patching.rb
|
139
|
-
- lib/portable_codec.rb
|
140
|
-
- lib/registry.rb
|
170
|
+
- lib/custom_assign.rb
|
141
171
|
- lib/scale_rb.rb
|
172
|
+
- lib/scale_rb/call_helper.rb
|
173
|
+
- lib/scale_rb/client/client_ext.rb
|
174
|
+
- lib/scale_rb/client/http_client.rb
|
175
|
+
- lib/scale_rb/client/ws_client.rb
|
176
|
+
- lib/scale_rb/codec.rb
|
177
|
+
- lib/scale_rb/codec_utils.rb
|
178
|
+
- lib/scale_rb/decode.rb
|
179
|
+
- lib/scale_rb/encode.rb
|
180
|
+
- lib/scale_rb/hasher.rb
|
181
|
+
- lib/scale_rb/metadata/metadata.rb
|
182
|
+
- lib/scale_rb/metadata/metadata_v10.rb
|
183
|
+
- lib/scale_rb/metadata/metadata_v11.rb
|
184
|
+
- lib/scale_rb/metadata/metadata_v12.rb
|
185
|
+
- lib/scale_rb/metadata/metadata_v13.rb
|
186
|
+
- lib/scale_rb/metadata/metadata_v14.rb
|
187
|
+
- lib/scale_rb/metadata/metadata_v9.rb
|
188
|
+
- lib/scale_rb/metadata/registry.rb
|
189
|
+
- lib/scale_rb/metadata/type_exp.rb
|
190
|
+
- lib/scale_rb/portable_registry.rb
|
191
|
+
- lib/scale_rb/storage_helper.rb
|
192
|
+
- lib/scale_rb/types.rb
|
193
|
+
- lib/scale_rb/utils.rb
|
142
194
|
- lib/scale_rb/version.rb
|
143
|
-
- lib/
|
195
|
+
- lib/type_enforcer.rb
|
144
196
|
- scale_rb.gemspec
|
145
197
|
- tea.yaml
|
146
198
|
homepage: https://github.com/wuminzhe/scale_rb
|
@@ -164,7 +216,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
164
216
|
- !ruby/object:Gem::Version
|
165
217
|
version: '0'
|
166
218
|
requirements: []
|
167
|
-
rubygems_version: 3.
|
219
|
+
rubygems_version: 3.5.16
|
168
220
|
signing_key:
|
169
221
|
specification_version: 4
|
170
222
|
summary: A Ruby SCALE Codec Library, and, Substrate RPC Client
|