scale_rb 0.4.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.devcontainer/devcontainer.json +21 -0
  3. data/Dockerfile +16 -0
  4. data/Gemfile +4 -4
  5. data/README.md +19 -6
  6. data/bin/console +0 -0
  7. data/bin/setup +0 -0
  8. data/examples/http_client_1.rb +0 -2
  9. data/examples/http_client_2.rb +0 -2
  10. data/examples/ws_client_1.rb +0 -2
  11. data/examples/ws_client_3.rb +1 -3
  12. data/examples/ws_client_4.rb +0 -2
  13. data/exe/metadata +9 -11
  14. data/lib/address.rb +1 -1
  15. data/lib/custom_assign.rb +92 -0
  16. data/lib/scale_rb/call_helper.rb +42 -0
  17. data/lib/{client → scale_rb/client}/client_ext.rb +12 -13
  18. data/lib/{client → scale_rb/client}/http_client.rb +3 -5
  19. data/lib/{client → scale_rb/client}/ws_client.rb +13 -20
  20. data/lib/scale_rb/codec.rb +25 -0
  21. data/lib/scale_rb/codec_utils.rb +128 -0
  22. data/lib/scale_rb/decode.rb +164 -0
  23. data/lib/scale_rb/encode.rb +150 -0
  24. data/lib/{hasher.rb → scale_rb/hasher.rb} +10 -8
  25. data/lib/scale_rb/metadata/metadata.rb +114 -0
  26. data/lib/{metadata → scale_rb/metadata}/metadata_v10.rb +0 -17
  27. data/lib/{metadata → scale_rb/metadata}/metadata_v11.rb +0 -17
  28. data/lib/{metadata → scale_rb/metadata}/metadata_v12.rb +0 -17
  29. data/lib/{metadata → scale_rb/metadata}/metadata_v13.rb +0 -17
  30. data/lib/{metadata → scale_rb/metadata}/metadata_v14.rb +18 -18
  31. data/lib/{metadata → scale_rb/metadata}/metadata_v9.rb +0 -17
  32. data/lib/scale_rb/metadata/registry.rb +263 -0
  33. data/lib/scale_rb/metadata/type_exp.rb +286 -0
  34. data/lib/scale_rb/portable_registry.rb +133 -0
  35. data/lib/{storage_helper.rb → scale_rb/storage_helper.rb} +16 -4
  36. data/lib/scale_rb/types.rb +233 -0
  37. data/lib/scale_rb/utils.rb +125 -0
  38. data/lib/scale_rb/version.rb +1 -1
  39. data/lib/scale_rb.rb +22 -30
  40. data/lib/type_enforcer.rb +170 -0
  41. data/scale_rb.gemspec +5 -0
  42. metadata +71 -19
  43. data/lib/codec.rb +0 -450
  44. data/lib/metadata/metadata.rb +0 -137
  45. data/lib/monkey_patching.rb +0 -115
  46. data/lib/portable_codec.rb +0 -285
  47. 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.1
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-08-05 00:00:00.000000000 Z
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/client/client_ext.rb
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/storage_helper.rb
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.3.7
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