ton-client-ruby 1.0.1 → 1.0.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d7dfd053a1c976028bc40dfe2cf9bb4750beee2688428ae7b8cfc9ff7e3c4d8d
4
- data.tar.gz: 651588ea67891811a9a847dda130c5cc2c6d1aac770213254b16c47ce4384238
3
+ metadata.gz: b17d66a87de3133d8f5a6f84d76615156c7bf9648da6825584a269c33cad85bb
4
+ data.tar.gz: dab93ec7b176f1d70478ee2bc95b0a77a47104586a49bc0acc43032ab87649ff
5
5
  SHA512:
6
- metadata.gz: 30e93f4c4d28c0b0d8af0766a5d9f632b1a3263ff63ac0edb312bb552b28404f5a2c5129fc418b9a18c440e7a6e6be8e18886c8377d83b28d58157d9052572e1
7
- data.tar.gz: 88ea3e6773d2d005a48ffdc7cb1ca4992f4a0955606814ceaed33c9f391b4842fac02d8043c35496fd69feb9eea70c34080b6c0b4f6b73eddf10122818c4dc46
6
+ metadata.gz: 26cd4d5b9531449e9922b2cdf4ec9222bd2101a15ee27740a68865492cebc8c08f799ea40b1f8ea35d116792c062ef6cbd7923e49784d8628163429e612f7a0c
7
+ data.tar.gz: deff9cde16ae317c0783bf1ddac5c7c65fb6c58c982adcaf601391d872eb95022351ecec7196b856327efe9de4c5bd0e0c07d6fa1b169a96c4eb28d63b8d14bf
data/bin/ton-client-ruby CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require File.dirname(__FILE__) + '/../code_generator/api_converter.rb'
4
- require File.dirname(__FILE__) + '/../code_generator/code_generator.rb'
3
+ require File.dirname(__FILE__) + '/../lib/code_generator/api_converter.rb'
4
+ require File.dirname(__FILE__) + '/../lib/code_generator/code_generator.rb'
5
5
 
6
6
  GEM_DIR = File.dirname(__FILE__) + '/..'
7
7
 
@@ -0,0 +1,399 @@
1
+ require 'json'
2
+ require 'byebug'
3
+ require File.dirname(__FILE__) + '/helpers.rb'
4
+
5
+
6
+
7
+ class ApiConverter
8
+ include InstanceHelpers
9
+
10
+ attr_reader :api_hash
11
+
12
+ def initialize(api_json)
13
+ @api_hash = JSON.parse(api_json)
14
+ end
15
+
16
+ def convert
17
+ ruby_types = ApiRubyTypes.new(version: api_hash['version'], modules: [])
18
+
19
+ (api_hash['modules'] || []).each do |mod|
20
+ new_mod = convert_module(mod)
21
+ ruby_types.modules << new_mod
22
+ ruby_types.all_types.merge!(new_mod.types_hash)
23
+ end
24
+
25
+ ruby_types
26
+ end
27
+
28
+ private
29
+
30
+ def convert_module(mod)
31
+ new_module = Module.new(name: mod['name'], alias: [], functions: [], enums: [], types: [], summary: mod['summary'], description: mod['description'])
32
+ (mod['types'] || []).each do |type|
33
+ if type['type'] == 'EnumOfTypes'
34
+ new_enum, new_struct = convert_fucking_enum_of_types(type)
35
+ new_module.enums << new_enum
36
+ new_module.types << new_struct
37
+ new_module.types_hash[new_enum.name] = new_enum
38
+ new_module.types_hash[new_struct.name] = new_struct
39
+ elsif type['type'] == 'EnumOfConsts'
40
+ new_type = convertEnumOfConsts(type)
41
+ new_module.enums << new_type
42
+ new_module.types_hash[new_type.name] = new_type
43
+ elsif type['type'] == 'Struct'
44
+ new_type = convertStruct(type)
45
+ new_module.types << new_type
46
+ new_module.types_hash[new_type.name] = new_type
47
+ elsif type['type'] == 'Number'
48
+ new_type = convertTypeAlias(type)
49
+ new_module.alias << new_type
50
+ new_module.types_hash[new_type.name] = new_type
51
+ else
52
+ raise "Unkown NEW TYPE for module #{type['name']} \"types\": #{type['types']}"
53
+ end
54
+ end
55
+
56
+ # /// FUNCTIONS
57
+ (mod['functions'] || []).each do |function|
58
+ result = ""
59
+ if function['result']['type'] == "Generic"
60
+ ref_type = function['result']['generic_args'].first&.send(:[], 'type') || ""
61
+ if ref_type == "Ref"
62
+ ref_name = function['result']['generic_args'].first&.send(:[], 'ref_name') || ""
63
+ if ref_name[/^(.+)\.(.+)$/]
64
+ mod = $1
65
+ type = $2
66
+ result = "#{lib_prefix}#{type}"
67
+ else
68
+ raise "Bad function result ref_name: #{ref_name}, function name: #{function['name']}, result: #{function['result']}"
69
+ end
70
+ elsif ref_type == "None"
71
+ result = "Void"
72
+ end
73
+ else
74
+ raise "New function result type !"
75
+ end
76
+
77
+ # /// function
78
+ newFunction = StructFunction.new(name: checkFunctionName(function['name']), arguments: [], result: result, summary: function['summary'], description: function['description'])
79
+ # /// FUNCTION PARAMETERS
80
+ paramsCount = 0
81
+ (function['params'] || []).each do |parameter|
82
+ if parameter['name'] == "params"
83
+ paramsCount += 1
84
+ if parameter['type'] == "Ref"
85
+ ref_name = parameter['ref_name'] || ""
86
+ if ref_name[/^(.+)\.(.+)$/]
87
+ mod = $1
88
+ type = $2
89
+ newFunction.arguments << FunctionArgument.new(name: "payload", type: "#{lib_prefix}#{type}")
90
+ else
91
+ raise "Bad function params ref_name: #{ref_name}, function name: #{function['name']}, result: #{function['result']}"
92
+ end
93
+ else
94
+ raise "NEW CASE! New parameter type: #{parameter['type']}"
95
+ end
96
+ end
97
+ raise "NEW CASE ! More then one parameter for functions !" if paramsCount > 1
98
+ end
99
+
100
+ new_module.functions << newFunction
101
+ end
102
+
103
+ new_module
104
+ end
105
+
106
+ def convertTypeAlias(from)
107
+ TypeAlias.new(name: "#{lib_prefix}#{from['name']}", type: generateType(from))
108
+ end
109
+
110
+ def convertStruct(from)
111
+ result = TypeStruct.new(name: "#{lib_prefix}#{from['name']}", parents: [], fields: [], functions: [])
112
+ (from['struct_fields'] || []).each do |field|
113
+ if isValidPropertyName(field['name'])
114
+ type = generateType(field)
115
+ if ( (from['name'] || "")[/Params/] || (field['name'] || "")[/input/]) && type[/Value/]
116
+ type = "Value"
117
+ elsif (field['name'] || "")[/^dictionary$/]
118
+ type = "#{lib_prefix}MnemonicDictionary"
119
+ elsif type[/Abi<Optional>/]
120
+ type = "Value<Optional>"
121
+ elsif type[/Abi/]
122
+ type = "Value"
123
+ end
124
+ property = StructField.new(name: checkPropertyName(field['name']), type: type, summary: field['summary'], description: field['description'])
125
+ result.fields << property
126
+ end
127
+ end
128
+
129
+ result
130
+ end
131
+
132
+ private def checkPropertyName(name)
133
+ result = ""
134
+ raise "Property Name is nil" unless name
135
+
136
+ case name
137
+ when "public"
138
+ result = "public"
139
+ else
140
+ result = name
141
+ end
142
+
143
+ return result
144
+ end
145
+
146
+ private def checkFunctionName(name)
147
+ result = ""
148
+ raise "Property Name is nil" unless name
149
+ case name
150
+ when "init"
151
+ result = "init"
152
+ else
153
+ result = name
154
+ end
155
+
156
+ return result
157
+ end
158
+
159
+ private def isValidPropertyName(name)
160
+ !(name || " ")[/\s/]
161
+ end
162
+
163
+ def convertEnumOfConsts(from)
164
+ result = TypeEnum.new(name: "#{lib_prefix}#{from['name']}", parents: [], cases: [], summary: from['summary'], description: from['description'])
165
+ (from['enum_consts'] || []).each do |enumConst|
166
+ caseName = enumConst['name']
167
+ caseValue = enumConst['value']
168
+ result.cases << EnumCase.new(name: caseName, value: caseValue, summary: enumConst['summary'], description: enumConst['description'])
169
+ end
170
+
171
+ return result
172
+ end
173
+
174
+ def convert_fucking_enum_of_types(enum)
175
+ result = [
176
+ TypeEnum.new(name: generate_enum_name(enum['name']), parents: [], cases: []),
177
+ TypeStruct.new(name: generate_struct_name(enum['name']), parents: [], fields: [], functions: [], summary: enum['summary'], description: enum['description'])
178
+ ]
179
+ properties_name_set = Set.new
180
+ properties = []
181
+ (enum['enum_types'] || []).each do |enum_type|
182
+ result[0].cases << EnumCase.new(name: enum_type['name'], value: enum_type['name'])
183
+ (enum_type['struct_fields'] || []).each do |field|
184
+ if !properties_name_set.include?(field['name'])
185
+ properties << field
186
+ end
187
+ properties_name_set << field['name']
188
+ end
189
+ end
190
+
191
+ result[1].fields << StructField.new(name: "type", type: generate_enum_name(enum['name']))
192
+ properties.each do |property|
193
+ type = generateType(property)
194
+ if property['name'][/^dictionary$/]
195
+ type = "#{lib_prefix}MnemonicDictionary"
196
+ end
197
+ result[1].fields << StructField.new(name: property['name'], type: type, summary: property['summary'], description: property['description'])
198
+ end
199
+ result
200
+ end
201
+
202
+ private def generateSimpleType(type)
203
+ tempType = ""
204
+
205
+ if type['type'] == "Ref"
206
+ if type['ref_name'] == "Value" || type['ref_name'] == "API"
207
+ tempType = "Value"
208
+ else
209
+ return type['optional'] ? "#{generateRefType(type['ref_name'] || "nil")}<Optional>" : generateRefType(type['ref_name'] || "nil")
210
+ end
211
+ else
212
+ tempType = type['type']
213
+ end
214
+ tempType = "#{tempType}<Optional>" if type['optional']
215
+
216
+ tempType
217
+ end
218
+
219
+ private def generateRefType(type)
220
+ result = ""
221
+
222
+ if type[/(.+)\.(.+)/]
223
+ mod = $1
224
+ typeName = $2
225
+ result = "#{lib_prefix}#{typeName}"
226
+ else
227
+ result = "#{lib_prefix}#{type}"
228
+ end
229
+
230
+ result
231
+ end
232
+
233
+ private def generateType(type)
234
+ if type['type'] == "Optional" && type['optional_inner']
235
+ type['optional'] = true
236
+ type['optional_inner']['optional'] = true
237
+ if type['optional_inner']['type'] == "Optional"
238
+ return generateType(type['optional_inner'])
239
+ else
240
+ return generateSimpleType(type['optional_inner'])
241
+ end
242
+ else
243
+ return generateSimpleType(type)
244
+ end
245
+ end
246
+
247
+ private def generate_enum_name(name)
248
+ "#{lib_prefix}#{name}#{lib_enum_postfix}"
249
+ end
250
+
251
+ private def generate_struct_name(name)
252
+ "#{lib_prefix}#{name}"
253
+ end
254
+ end
255
+
256
+
257
+ class ApiRubyTypes
258
+ attr_accessor :version
259
+ attr_accessor :modules
260
+ attr_accessor :all_types
261
+
262
+ def initialize(params)
263
+ @all_types = {}
264
+ params.each do |k, v|
265
+ if self.respond_to?(k.to_sym)
266
+ instance_variable_set("@#{k}".to_sym, v)
267
+ end
268
+ end
269
+ end
270
+ end
271
+
272
+ class Module
273
+ attr_accessor :name
274
+ attr_accessor :summary
275
+ attr_accessor :description
276
+ attr_accessor :alias
277
+ attr_accessor :enums
278
+ attr_accessor :types
279
+ attr_accessor :types_hash
280
+ attr_accessor :functions
281
+ attr_accessor :summary
282
+ attr_accessor :description
283
+
284
+ def initialize(params)
285
+ @types_hash = {}
286
+ params.each do |k, v|
287
+ if self.respond_to?(k.to_sym)
288
+ instance_variable_set("@#{k}".to_sym, v)
289
+ end
290
+ end
291
+ end
292
+ end
293
+
294
+ class TypeAlias
295
+ attr_accessor :name
296
+ attr_accessor :type
297
+ attr_accessor :summary
298
+ attr_accessor :description
299
+
300
+ def initialize(params)
301
+ params.each do |k, v|
302
+ if self.respond_to?(k.to_sym)
303
+ instance_variable_set("@#{k}".to_sym, v)
304
+ end
305
+ end
306
+ end
307
+ end
308
+
309
+ class TypeEnum
310
+ attr_accessor :name
311
+ attr_accessor :parents
312
+ attr_accessor :cases
313
+ attr_accessor :summary
314
+ attr_accessor :description
315
+
316
+ def initialize(params)
317
+ params.each do |k, v|
318
+ if self.respond_to?(k.to_sym)
319
+ instance_variable_set("@#{k}".to_sym, v)
320
+ end
321
+ end
322
+ end
323
+ end
324
+
325
+ class EnumCase
326
+ attr_accessor :name
327
+ attr_accessor :value
328
+ attr_accessor :summary
329
+ attr_accessor :description
330
+
331
+ def initialize(params)
332
+ params.each do |k, v|
333
+ if self.respond_to?(k)
334
+ instance_variable_set("@#{k}".to_sym, v)
335
+ end
336
+ end
337
+ end
338
+ end
339
+
340
+ class TypeStruct
341
+ attr_accessor :name
342
+ attr_accessor :parents
343
+ attr_accessor :fields
344
+ attr_accessor :functions
345
+ attr_accessor :summary
346
+ attr_accessor :description
347
+
348
+ def initialize(params)
349
+ params.each do |k, v|
350
+ if self.respond_to?(k.to_sym)
351
+ instance_variable_set("@#{k}".to_sym, v)
352
+ end
353
+ end
354
+ end
355
+ end
356
+
357
+ class StructField
358
+ attr_accessor :name
359
+ attr_accessor :type
360
+ attr_accessor :summary
361
+ attr_accessor :description
362
+
363
+ def initialize(params)
364
+ params.each do |k, v|
365
+ if self.respond_to?(k.to_sym)
366
+ instance_variable_set("@#{k}".to_sym, v)
367
+ end
368
+ end
369
+ end
370
+ end
371
+
372
+ class StructFunction
373
+ attr_accessor :name
374
+ attr_accessor :arguments
375
+ attr_accessor :result
376
+ attr_accessor :summary
377
+ attr_accessor :description
378
+
379
+ def initialize(params)
380
+ params.each do |k, v|
381
+ if self.respond_to?(k.to_sym)
382
+ instance_variable_set("@#{k}".to_sym, v)
383
+ end
384
+ end
385
+ end
386
+ end
387
+
388
+ class FunctionArgument
389
+ attr_accessor :name
390
+ attr_accessor :type
391
+
392
+ def initialize(params)
393
+ params.each do |k, v|
394
+ if self.respond_to?(k.to_sym)
395
+ instance_variable_set("@#{k}".to_sym, v)
396
+ end
397
+ end
398
+ end
399
+ end
@@ -0,0 +1,318 @@
1
+ require 'byebug'
2
+ require 'json'
3
+ require File.dirname(__FILE__) + '/helpers.rb'
4
+
5
+ class CodeGenerator
6
+ include InstanceHelpers
7
+
8
+ attr_accessor :types
9
+ attr_accessor :root_dir
10
+
11
+ TAB = " "
12
+
13
+ def initialize(types, root_dir)
14
+ @types = types
15
+ @root_dir = root_dir
16
+ end
17
+
18
+ def generate_self_code
19
+ generateModules(types)
20
+ generateReadme(types)
21
+ end
22
+
23
+ private
24
+
25
+ def generateModules(types)
26
+ types.modules.each do |mod|
27
+ modulesFolder = root_dir + "/lib/ton-client-ruby/Client"
28
+ moduleFilePath = "#{modulesFolder}/#{mod.name.capitalize}.rb"
29
+ newModuleContent = ""
30
+ if mod.name == "client"
31
+ newModuleContent = generateClientModule(mod, types.modules)
32
+ else
33
+ newModuleContent = generateModule(mod)
34
+ end
35
+ if File.exists?(moduleFilePath)
36
+ File.delete(moduleFilePath)
37
+ end
38
+ File.open(moduleFilePath, 'w+') { |f| f.write(newModuleContent) }
39
+ end
40
+
41
+ p 'generate_self_code ok'
42
+ end
43
+
44
+ def generateReadme(types)
45
+ readmePath = root_dir + "/README.md"
46
+ content = %{
47
+ # Ruby Client for Free TON SDK
48
+
49
+ [![GEM](https://img.shields.io/badge/ruby-gem-green)]()
50
+
51
+ ## Install
52
+
53
+ Install gem
54
+ ```bash
55
+ gem install ton-client-ruby
56
+ ```
57
+
58
+ Install TON-SDK
59
+ ```bash
60
+ ton-client-ruby setup
61
+ ```
62
+
63
+ ### Manual build FreeTON SDK
64
+ 0. Install Rust to your OS
65
+ 1. git clone https://github.com/tonlabs/TON-SDK
66
+ 2. cd ./TON-SDK
67
+ 3. cargo update
68
+ 4. cargo build --release
69
+
70
+ ## Usage
71
+
72
+ ```ruby
73
+ # For MAcOS
74
+ TonClient.configure { |config| config.ffi_lib(./TON-SDK/target/release/libton_client.dylib) }
75
+ # For Linux
76
+ # TonClient.configure { |config| config.ffi_lib(./TON-SDK/target/release/libton_client.so) }
77
+
78
+ client = TonClient.create(config: {network: {server_address: "net.ton.dev"}})
79
+
80
+ # All methods are asynchronous
81
+
82
+ # example: call method for Crypto module
83
+ payload = {composite: '17ED48941A08F981'}
84
+ client.crypto.factorize(payload) do |response|
85
+ p response.result['factors']
86
+ end
87
+
88
+ # e.g. ...
89
+ ```\n\n
90
+ }
91
+ content << "## All Modules, methods and types\n\n"
92
+
93
+ # types
94
+ content << "<details>\n#{TAB}<summary>Types</summary>\n\n"
95
+
96
+ content << "#{customTypes()}\n"
97
+
98
+ types.modules.each do |mod|
99
+ (mod.enums || []).each do |type|
100
+ content << checkComment(type.summary, 0) if type.summary
101
+ content << checkComment(type.description, 0) if type.description
102
+ content << "\n- #### #{type.name}\n"
103
+ (type.cases || []).each do |enum_case|
104
+ content << "#{checkComment(enum_case.summary, 1).gsub(/#/, '')}" if enum_case.summary
105
+ content << "#{checkComment(enum_case.description, 1).gsub(/#/, '')}" if enum_case.description
106
+ content << "#{TAB}- case #{enum_case.name} = #{enum_case.value}\n\n"
107
+ end
108
+ end
109
+
110
+ (mod.types || []).each do |type|
111
+ content << checkComment(type.summary, 0) if type.summary
112
+ content << checkComment(type.description, 0) if type.description
113
+ content << "\n- #### #{type.name}\n"
114
+ (type.fields || []).each do |field|
115
+ content << "#{checkComment(field.summary, 1).gsub(/#/, '')}\n" if field.summary
116
+ content << "#{checkComment(field.description, 1).gsub(/#/, '')}\n" if field.description
117
+ content << "#{TAB}- #{field.name}: #{field.type}\n\n"
118
+ end
119
+ end
120
+ end
121
+ content << "</details>\n\n"
122
+
123
+ # methods
124
+ types.modules.each do |mod|
125
+ content << "<details>\n#{TAB}<summary>#{mod.name&.upcase}</summary>\n\n"
126
+ (mod.functions || []).each do |function|
127
+ content << "```ruby\n"
128
+ content << checkComment(function.summary, 2) if function.summary
129
+ content << checkComment(function.description, 2) if function.description
130
+ content << "\n#{TAB}#{TAB}def #{function.name}"
131
+ if function.arguments.empty?
132
+ content << "(&block)\n"
133
+ else
134
+ content << "(payload, &block)\n"
135
+ end
136
+ content << getFunctionComment(function, types)
137
+ content << "```\n"
138
+ end
139
+ content << "</details>\n\n"
140
+ end
141
+
142
+ content << %{
143
+ \n## Tests
144
+
145
+ 1. create __.env.test__ file inside root directory of this library with variables
146
+
147
+ example for NodeSE
148
+ ```
149
+ spec_ffi=./TON-SDK/target/release/libton_client.dylib
150
+ server_address=http://localhost:80
151
+ giver_abi_name=GiverNodeSE
152
+ giver_amount=10000000000
153
+ ```
154
+ 2. Run tests: inside folder of this library execute this commands
155
+ **rspec spec/binding.rb**
156
+ **rspec spec/client.rb**
157
+ **rspec spec/context.rb**
158
+ **rspec spec/abi.rb**
159
+ **rspec spec/boc.rb**
160
+ **rspec spec/crypto.rb**
161
+ **rspec spec/net.rb**
162
+ **rspec spec/processing.rb**
163
+ **rspec spec/tvm.rb**
164
+ **rspec spec/utils.rb**
165
+ }
166
+ content = checkContent(content)
167
+ if File.exists?(readmePath)
168
+ File.delete(readmePath)
169
+ end
170
+ File.open(readmePath, 'w+') { |f| f.write(content) }
171
+ end
172
+
173
+ private def checkContent(content)
174
+ content.gsub!(/^([\s]+)# RESPONSE/, "\n\\1# RESPONSE")
175
+ content.gsub(/<Optional>/i, '&lt;Optional&gt;')
176
+ end
177
+
178
+ def customTypes
179
+ content = %{
180
+ - #### #{lib_prefix}MnemonicDictionary
181
+ #{TAB}- case TON = 0
182
+ #{TAB}- case ENGLISH = 1
183
+ #{TAB}- case CHINESE_SIMPLIFIED = 2
184
+ #{TAB}- case CHINESE_TRADITIONAL = 3
185
+ #{TAB}- case FRENCH = 4
186
+ #{TAB}- case ITALIAN = 5
187
+ #{TAB}- case JAPANESE = 6
188
+ #{TAB}- case KOREAN = 7
189
+ #{TAB}- case SPANISH = 8
190
+ }
191
+ content
192
+ end
193
+
194
+ private def checkComment(string, tabs = 1)
195
+ replacedString = "\n"
196
+ tab = ""
197
+ tabs.times do |i|
198
+ tab << TAB
199
+ end
200
+ comment = "#"
201
+ replacedString << "#{tab}#{comment} "
202
+ symbolsWithSpace = "\\.|\\:|\\!|\\?|\\;"
203
+ regxp = /([^#{symbolsWithSpace}])\n/
204
+ result = string
205
+ result.gsub!(/\n+/, "\n")
206
+ result.gsub!(/ \n/, "\n#{comment} ")
207
+ result.gsub!(/(#{symbolsWithSpace})\s*\n/, "\\1#{replacedString}")
208
+ result.gsub!(regxp, "\\1")
209
+ "#{tab}# #{result}"
210
+ end
211
+
212
+ private def generateClientModule(mod, modules)
213
+ content = "module TonClient\n\n#{TAB}class #{mod.name.capitalize}\n#{TAB}#{TAB}include CommonInstanceHelpers\n\n"
214
+ content << "#{TAB}#{TAB}attr_reader :core, :context\n"
215
+ content << "#{TAB}#{TAB}private_accessor "
216
+ modules.each_with_index do |m, i|
217
+ next if m.name.downcase == 'client'
218
+ content << ((modules.size - 1) == i ? ":_#{m.name}\n" : ":_#{m.name}, ")
219
+ end
220
+ content << "#{TAB}#{TAB}MODULE = self.to_s.downcase.gsub(/^(.+::|)(\\w+)$/, '\\2').freeze\n\n"
221
+ content << "#{TAB}#{TAB}def initialize(context: Context.new, core: TonClient::TonBinding)\n"
222
+ content << "#{TAB}#{TAB}#{TAB}@context = context\n"
223
+ content << "#{TAB}#{TAB}#{TAB}@core = core\n#{TAB}#{TAB}end\n\n"
224
+ content << "#{TAB}#{TAB}def destroy_context\n"
225
+ content << "#{TAB}#{TAB}#{TAB}core.tc_destroy_context(context.id)\n#{TAB}#{TAB}end\n\n"
226
+ modules.each_with_index do |m, i|
227
+ next if m.name.downcase == 'client'
228
+ content << "#{TAB}#{TAB}def #{m.name}\n"
229
+ content << "#{TAB}#{TAB}#{TAB}_#{m.name} ||= #{m.name.capitalize}.new(context: context)\n"
230
+ content << "#{TAB}#{TAB}end\n\n"
231
+ end
232
+
233
+ mod.functions.each do |func|
234
+ content << gen_function(func, types)
235
+ end
236
+
237
+ content << "#{TAB}end\n"
238
+ content << "end\n\n"
239
+
240
+ content
241
+ end
242
+
243
+ private def generateModule(mod)
244
+ content = "module TonClient\n\n#{TAB}class #{mod.name.capitalize}\n#{TAB}#{TAB}include CommonInstanceHelpers\n\n"
245
+ content << "#{TAB}#{TAB}attr_reader :core, :context\n"
246
+ content << "#{TAB}#{TAB}MODULE = self.to_s.downcase.gsub(/^(.+::|)(\\w+)$/, '\\2').freeze\n\n"
247
+ content << "#{TAB}#{TAB}def initialize(context: Context.new, core: TonClient::TonBinding)\n"
248
+ content << "#{TAB}#{TAB}#{TAB}@context = context\n"
249
+ content << "#{TAB}#{TAB}#{TAB}@core = core\n"
250
+ content << "#{TAB}#{TAB}end\n\n"
251
+
252
+ mod.functions.each do |func|
253
+ content << gen_function(func, types)
254
+ end
255
+
256
+ content << "#{TAB}end\n"
257
+ content << "end\n\n"
258
+
259
+ content
260
+ end
261
+
262
+ private def gen_function(function, types)
263
+ content = getFunctionComment(function, types)
264
+ content << "#{TAB}#{TAB}def #{function.name}"
265
+ if function.arguments.empty?
266
+ content << "(&block)\n"
267
+ content << "#{TAB}#{TAB}#{TAB}core.requestLibrary(context: context.id, method_name: full_method_name(MODULE, __method__.to_s), payload: {}, &block)\n"
268
+ else
269
+ content << "(payload, &block)\n"
270
+ content << "#{TAB}#{TAB}#{TAB}core.requestLibrary(context: context.id, method_name: full_method_name(MODULE, __method__.to_s), payload: payload, &block)\n"
271
+ end
272
+ content << "#{TAB}#{TAB}end\n\n"
273
+
274
+ content
275
+ end
276
+
277
+ def getFunctionComment(function, types)
278
+ content = ''
279
+ if argument = function.arguments.first
280
+ content << "#{TAB}#{TAB}# INPUT: #{argument.type}\n"
281
+ if types.all_types[argument.type].respond_to?(:fields)
282
+ types.all_types[argument.type].fields.each do |arg|
283
+ content << "#{TAB}#{TAB}# #{arg.name}: #{arg.type} - "
284
+ content << "#{TAB}#{TAB}# #{checkComment(arg.summary, 2)}" if arg.summary
285
+ content << "#{TAB}#{TAB}# #{checkComment(arg.description, 2)}" if arg.description
286
+ content << "\n"
287
+ end
288
+ elsif types.all_types[argument.type].respond_to?(:cases)
289
+ end
290
+ end
291
+
292
+ if types.all_types[function.result]
293
+ content << "#{TAB}#{TAB}# RESPONSE: #{function.result}\n"
294
+ if types.all_types[function.result].respond_to?(:fields)
295
+ types.all_types[function.result].fields.each do |arg|
296
+ content << "#{TAB}#{TAB}# #{arg.name}: #{arg.type} - "
297
+ content << "#{TAB}#{TAB}# #{checkComment(arg.summary, 2)}" if arg.summary
298
+ content << "#{TAB}#{TAB}# #{checkComment(arg.description, 2)}" if arg.description
299
+ content << "\n"
300
+ end
301
+ elsif types.all_types[function.result].respond_to?(:cases)
302
+ end
303
+ end
304
+
305
+ content
306
+ end
307
+ end
308
+
309
+
310
+
311
+
312
+
313
+
314
+
315
+
316
+
317
+
318
+
@@ -0,0 +1,13 @@
1
+ require 'json'
2
+ require 'byebug'
3
+
4
+ module InstanceHelpers
5
+
6
+ def lib_prefix
7
+ ''
8
+ end
9
+
10
+ def lib_enum_postfix
11
+ ''
12
+ end
13
+ end
@@ -1,3 +1,3 @@
1
1
  module TonClient
2
- VERSION = "1.0.1"
2
+ VERSION = "1.0.2"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ton-client-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - nerzh
@@ -103,6 +103,9 @@ extensions: []
103
103
  extra_rdoc_files: []
104
104
  files:
105
105
  - bin/ton-client-ruby
106
+ - lib/code_generator/api_converter.rb
107
+ - lib/code_generator/code_generator.rb
108
+ - lib/code_generator/helpers.rb
106
109
  - lib/ton-client-ruby.rb
107
110
  - lib/ton-client-ruby/Binding/binding.rb
108
111
  - lib/ton-client-ruby/Binding/struct.rb