ton-client-ruby 1.0.1 → 1.0.2

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