ton-client-ruby 1.0.0 → 1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0321af077acd0b4c971b583f6448bbb0c9633abfd72be60a9a442bd595f74bc2
4
- data.tar.gz: 3e2bca8f73c5dd23dc5c60be5655d2f777d58a5870d1176d3633ef69d0eb52b4
3
+ metadata.gz: 7d9f09aaabae6ed86f5adc9a77082f2c94ad685437fb7457e490253086ca80b5
4
+ data.tar.gz: 6e2e1b73de3671c362fbb0ebdb919e9fdc7b94fabe8302b46fc3159ba42100af
5
5
  SHA512:
6
- metadata.gz: 242a9a7821f494ef4165d3c3b25d680c194b9be860a766fab753d44b05332a1c5a14e5674347a0af31f52af34e751a980352070000c1cadd67b4949e88faba11
7
- data.tar.gz: fdca0400955e2d5010bde1ed0ca3b938f43a9198c315e8bed2cca7d9518bca57ee02f1447576a5dd52b6a1c03b26601fbd641d2c3d3b099ae68beec2ffacef1c
6
+ metadata.gz: 621cc074093d4de7603aa1135dc597681aaf72337f42bab12bb9e3692f58462f7eb7696e04b029945abda6c85dbc584bc8d72804d89882d1d98966a69a139acd
7
+ data.tar.gz: 9cf4d820e210ab28a1a64dbf6474b954de1b35166c692321b648464b3258b88a033678382a222237814a93b206c0f5ce07734399e0bd72774ff5a1f207a856be
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.dirname(__FILE__) + '/../lib/code_generator/api_converter.rb'
4
+ require File.dirname(__FILE__) + '/../lib/code_generator/code_generator.rb'
5
+
6
+ GEM_DIR = File.dirname(__FILE__) + '/..'
7
+
8
+ if ARGV[0] == 'update'
9
+ if !ARGV[1]
10
+ puts ''
11
+ puts ''
12
+ p "PLEASE DOWNLOAD api.json from https://github.com/tonlabs/TON-SDK/blob/master/tools/api.json and pass as second parameter."
13
+ p "Example: ton-client-ruby update ./api.json"
14
+ puts ''
15
+ return
16
+ end
17
+ api_json_path = ARGV[1]
18
+ json = ''
19
+ if File.exists?(api_json_path)
20
+ json = File.read(api_json_path)
21
+ else
22
+ p "Current directory: #{Dir.pwd}. File #{api_json_path} is not exist"
23
+ exit 0
24
+ end
25
+ converter = ApiConverter.new(json)
26
+ types = converter.convert
27
+ generator = CodeGenerator.new(types, GEM_DIR)
28
+ generator.generate_self_code
29
+ elsif ARGV[0] == 'update' && ARGV[1] == nil
30
+ p 'soon from github'
31
+ elsif ARGV[0] == 'setup'
32
+ raise "\nPLEASE INSTALL RUST TO YOUR SYSTEM. \nTry this command: \ncurl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh" if `which rustc`.strip.empty?
33
+ unless Dir.exist?("#{GEM_DIR}/TON-SDK")
34
+ system("cd #{GEM_DIR} && git clone https://github.com/tonlabs/TON-SDK ./TON-SDK")
35
+ end
36
+ system("cd #{GEM_DIR}/TON-SDK && git pull --ff-only")
37
+ system("cd #{GEM_DIR}/TON-SDK && cargo update")
38
+ system("cd #{GEM_DIR}/TON-SDK && cargo build --release")
39
+ puts ''
40
+ puts "PATH TO YOR DYNAMIC LIBRARY IS: #{GEM_DIR}/TON-SDK/target/release/libton_client.dylib"
41
+ puts ''
42
+ end
@@ -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