class_from_son 0.1.8 → 0.2.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/README.md +14 -2
- data/lib/class_from_SON.rb +122 -10
- data/test/test_class_from_son.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7fe5463050c5bf5076026c3035dd5bf5e470659327ea19f6d8306042d96660bf
|
4
|
+
data.tar.gz: ea0270609324bd424d40ab09fa3b4da93d02689356e89d80b43c5a67cf5c6200
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 43cdeb8b35bd888eb0a21516e815e961d84d6714a522f49e16c628752954e67e4159afcd8552ba0741d204d26d824fd4b1b38b68dab8329ecf6ebdf34a1c642f
|
7
|
+
data.tar.gz: 549407b5e6149da0da5a826658591fdb76cc672b01bb157f81189fe66fe9fb37ab8de1424b80834f0758997045307133e44dbe2dfef3525b3a000574e18d411a
|
data/README.md
CHANGED
@@ -31,6 +31,12 @@ or
|
|
31
31
|
ruby -e "require 'class_from_son'; ClassFromSON.generate :ruby, my_json_string, :json"
|
32
32
|
```
|
33
33
|
|
34
|
+
Advanced use :
|
35
|
+
|
36
|
+
```
|
37
|
+
ruby -e "require 'class_from_son'; ClassFromSON.generate :ruby, my_json_string, :json, true, false, true, '../write/files/somewhere/else'"
|
38
|
+
```
|
39
|
+
|
34
40
|
Method parameter explanations :
|
35
41
|
|
36
42
|
```
|
@@ -42,7 +48,10 @@ Method parameter explanations :
|
|
42
48
|
# source_lang is symbol or nil (if nil, source language will be determined from the file extension)
|
43
49
|
# make_file flag defaults to true; set to false if you do not want files to be created by this method
|
44
50
|
# force_file flag is false; set to true if you wish to overwrite matching destination files (use with caution!)
|
45
|
-
|
51
|
+
# lenient_mode flag is true; if the SON contains different objects with the same name (e.g. "data") then these will be treated
|
52
|
+
# as different objects with a _1, _2, etc. suffix. If this flag is false and these different objects are present, then errors will occur
|
53
|
+
# custom_file_path is nil; set to an absoulte or relative path to have the new files be written to that location
|
54
|
+
def ClassFromSON.generate_from_file(dest_lang, file, source_lang = nil, make_file = true, force_file = false, lenient_mode = true, custom_file_path = nil)
|
46
55
|
```
|
47
56
|
|
48
57
|
```
|
@@ -54,5 +63,8 @@ def ClassFromSON.generate_from_file(dest_lang, file, source_lang, make_file = tr
|
|
54
63
|
# source_lang is symbol
|
55
64
|
# make_file flag defaults to true; set to false if you do not want files to be created by this method
|
56
65
|
# force_file flag is false; set to true if you wish to overwrite matching destination files (use with caution!)
|
57
|
-
|
66
|
+
# lenient_mode flag is true; if the SON contains different objects with the same name (e.g. "data") then these will be treated
|
67
|
+
# as different objects with a _1, _2, etc. suffix. If this flag is false and these different objects are present, then errors will occur
|
68
|
+
# custom_file_path is nil; set to an absoulte or relative path to have the new files be written to that location
|
69
|
+
def ClassFromSON.generate(dest_lang, source, source_lang, make_file = true, force_file = false, lenient_mode = true, custom_file_path = nil)
|
58
70
|
```
|
data/lib/class_from_SON.rb
CHANGED
@@ -172,6 +172,7 @@ class ClassFromSON
|
|
172
172
|
|
173
173
|
# Returns code representing the start of the class
|
174
174
|
def generate_class_start(name)
|
175
|
+
# TODO make this more readable
|
175
176
|
case @language
|
176
177
|
when :java
|
177
178
|
start = <<-START
|
@@ -199,7 +200,16 @@ import lombok.Setter;
|
|
199
200
|
public class #{convert_custom_class_type(name)} {
|
200
201
|
START
|
201
202
|
when :ruby
|
202
|
-
|
203
|
+
case @mode
|
204
|
+
when :json
|
205
|
+
start = <<-START
|
206
|
+
require 'json'
|
207
|
+
|
208
|
+
class #{convert_custom_class_type(name)}
|
209
|
+
START
|
210
|
+
else
|
211
|
+
error_and_exit "Cannot parse mode #{@mode}"
|
212
|
+
end
|
203
213
|
else
|
204
214
|
error_and_exit "Could not convert to output language #{@language}"
|
205
215
|
end
|
@@ -285,7 +295,7 @@ START
|
|
285
295
|
def generate_ruby_code_from_attributes(attributes)
|
286
296
|
code = []
|
287
297
|
names = []
|
288
|
-
attributes.each {|att| names << att[:name]}
|
298
|
+
attributes.each {|att| names << att[:name].snakecase}
|
289
299
|
|
290
300
|
# Instance variables
|
291
301
|
names.each do |name|
|
@@ -294,12 +304,74 @@ START
|
|
294
304
|
code << "" # An empty string is enough to trigger a newline
|
295
305
|
|
296
306
|
# Constructor
|
297
|
-
|
307
|
+
# This is deliberately commented out, in favour of self.from_hash
|
308
|
+
code << "\t# Using self.from_hash(hash) is usually better, but this code is here in case you prefer this style of constructor"
|
309
|
+
code << "\t# def initialize(#{names.join(", ")})"
|
298
310
|
names.each do |name|
|
299
|
-
code << "\t\t@#{name} = #{name}"
|
311
|
+
code << "\t\t# @#{name} = #{name}"
|
300
312
|
end
|
313
|
+
code << "\t# end"
|
314
|
+
code
|
315
|
+
end
|
316
|
+
|
317
|
+
# Returns code for a from_SON and to_SON method
|
318
|
+
def generate_from_and_to_methods(classname, attributes)
|
319
|
+
case @language
|
320
|
+
when :java, :java_lombok
|
321
|
+
return generate_java_from_and_to_methods(classname, attributes)
|
322
|
+
when :ruby
|
323
|
+
return generate_ruby_from_and_to_methods(classname, attributes)
|
324
|
+
else
|
325
|
+
error_and_exit "Could not convert to output language #{@language}"
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
# Returns Java code for a from_SON and to_SON method
|
330
|
+
def generate_java_from_and_to_methods(classname, attributes)
|
331
|
+
code = []
|
332
|
+
# TODO
|
333
|
+
code
|
334
|
+
end
|
335
|
+
|
336
|
+
# Returns Ruby code for a from_SON and to_SON method
|
337
|
+
def generate_ruby_from_and_to_methods(classname, attributes)
|
338
|
+
code = []
|
339
|
+
names = []
|
340
|
+
attributes.each {|att| names << att[:name].snakecase}
|
341
|
+
|
342
|
+
# from_hash method
|
343
|
+
code << ""
|
344
|
+
code << "\tdef self.from_hash(h)"
|
345
|
+
code << "\t\to = self.new"
|
346
|
+
names.each do |name|
|
347
|
+
code << "\t\to.#{name} = h[:#{name}]"
|
348
|
+
end
|
349
|
+
code << "\t\to"
|
301
350
|
code << "\tend"
|
302
351
|
|
352
|
+
# from_SON method
|
353
|
+
code << ""
|
354
|
+
code << "\tdef self.from_#{@mode}(#{@mode})"
|
355
|
+
case @mode
|
356
|
+
when :json
|
357
|
+
code << "\t\tself.from_hash(JSON.parse(#{@mode}))"
|
358
|
+
# TODO other input languages, e.g. XML, YAML
|
359
|
+
end
|
360
|
+
code << "\tend"
|
361
|
+
|
362
|
+
# to_SON method
|
363
|
+
code << ""
|
364
|
+
code << "\tdef to_#{@mode}"
|
365
|
+
code << "\t\th = {}"
|
366
|
+
names.each do |name|
|
367
|
+
code << "\t\th[:#{name}] = @#{name}"
|
368
|
+
end
|
369
|
+
case @mode
|
370
|
+
when :json
|
371
|
+
code << "\t\tJSON.generate(h)"
|
372
|
+
# TODO other input languages, e.g. XML, YAML
|
373
|
+
end
|
374
|
+
code << "\tend"
|
303
375
|
code
|
304
376
|
end
|
305
377
|
|
@@ -337,6 +409,7 @@ START
|
|
337
409
|
end
|
338
410
|
|
339
411
|
lines << generate_code_from_attributes(attributes)
|
412
|
+
lines << generate_from_and_to_methods(classname, attributes)
|
340
413
|
lines << generate_class_end
|
341
414
|
lines.flatten!
|
342
415
|
this_file[:contents] = lines.join("\n")
|
@@ -356,13 +429,16 @@ START
|
|
356
429
|
# source_lang is symbol or nil (if nil, source language will be determined from the file extension)
|
357
430
|
# make_file flag defaults to true; set to false if you do not want files to be created by this method
|
358
431
|
# force_file flag is false; set to true if you wish to overwrite matching destination files (use with caution!)
|
359
|
-
|
432
|
+
# lenient_mode flag is true; if the SON contains different objects with the same name (e.g. "data") then these will be treated
|
433
|
+
# as different objects with a _1, _2, etc. suffix. If this flag is false and these different objects are present, then errors will occur
|
434
|
+
# custom_file_path is nil; set to an absoulte or relative path to have the new files be written to that location
|
435
|
+
def ClassFromSON.generate_from_file(dest_lang, file, source_lang = nil, make_file = true, force_file = false, lenient_mode = true, custom_file_path = nil)
|
360
436
|
|
361
437
|
error_and_exit "Could not locate file #{file}" unless File.exists?(file)
|
362
438
|
|
363
439
|
source_lang ||= File.extname(file).gsub(".", "")
|
364
440
|
source = File.readlines(file).join
|
365
|
-
ClassFromSON.generate(dest_lang, source, source_lang, make_file, force_file)
|
441
|
+
ClassFromSON.generate(dest_lang, source, source_lang, make_file, force_file, lenient_mode, custom_file_path)
|
366
442
|
|
367
443
|
# o = ClassFromSON.new
|
368
444
|
# o.generate(dest_lang, source, source_lang, make_file)
|
@@ -376,9 +452,12 @@ START
|
|
376
452
|
# source_lang is symbol
|
377
453
|
# make_file flag defaults to true; set to false if you do not want files to be created by this method
|
378
454
|
# force_file flag is false; set to true if you wish to overwrite matching destination files (use with caution!)
|
379
|
-
|
455
|
+
# lenient_mode flag is true; if the SON contains different objects with the same name (e.g. "data") then these will be treated
|
456
|
+
# as different objects with a _1, _2, etc. suffix. If this flag is false and these different objects are present, then errors will occur
|
457
|
+
# custom_file_path is nil; set to an absoulte or relative path to have the new files be written to that location
|
458
|
+
def ClassFromSON.generate(dest_lang, source, source_lang, make_file = true, force_file = false, lenient_mode = true, custom_file_path = nil)
|
380
459
|
o = ClassFromSON.new
|
381
|
-
o.generate(dest_lang, source, source_lang, make_file, force_file)
|
460
|
+
o.generate(dest_lang, source, source_lang, make_file, force_file, lenient_mode, custom_file_path)
|
382
461
|
end
|
383
462
|
|
384
463
|
# Will generate classes from a SON string.
|
@@ -389,7 +468,10 @@ START
|
|
389
468
|
# source_lang is symbol
|
390
469
|
# make_file flag defaults to true; set to false if you do not want files to be created by this method
|
391
470
|
# force_file flag is false; set to true if you wish to overwrite matching destination files (use with caution!)
|
392
|
-
|
471
|
+
# lenient_mode flag is true; if the SON contains different objects with the same name (e.g. "data") then these will be treated
|
472
|
+
# as different objects with a _1, _2, etc. suffix. If this flag is false and these different objects are present, then errors will occur
|
473
|
+
# custom_file_path is nil; set to an absoulte or relative path to have the new files be written to that location
|
474
|
+
def generate(dest_lang, source, source_lang, make_file = true, force_file = false, lenient_mode = true, custom_file_path = nil)
|
393
475
|
|
394
476
|
error_and_exit "Please supply first argument as a Symbol" unless dest_lang.class == Symbol
|
395
477
|
|
@@ -434,16 +516,46 @@ START
|
|
434
516
|
top_level_classname = generate_top_level_name
|
435
517
|
output_classes = generate_output_classes(hash, top_level_classname).flatten # returns an array
|
436
518
|
|
519
|
+
# Set the directory that the files will be written into
|
520
|
+
if custom_file_path
|
521
|
+
# This caters for both absolute & relative file paths
|
522
|
+
file_path = File.absolute_path(custom_file_path)
|
523
|
+
else
|
524
|
+
file_path = Dir.getwd
|
525
|
+
end
|
526
|
+
|
527
|
+
# Track the names of the classes/files we have written so far
|
528
|
+
written_file_names = []
|
529
|
+
|
437
530
|
if make_file
|
438
531
|
output_classes.each do |out|
|
439
532
|
name = out[:name_with_ext]
|
533
|
+
# Check the name against the files we have already written
|
534
|
+
if written_file_names.include?(name)
|
535
|
+
if lenient_mode
|
536
|
+
# Let us increment the name, e.g. "data.rb" -> "data_1.rb", "data_2.rb", etc.
|
537
|
+
increment = 1
|
538
|
+
new_name = name.gsub(@extension, "_#{increment}#{@extension}")
|
539
|
+
while written_file_names.include?(new_name)
|
540
|
+
increment += 1
|
541
|
+
new_name = name.gsub(@extension, "_#{increment}#{@extension}")
|
542
|
+
end
|
543
|
+
name = new_name
|
544
|
+
else
|
545
|
+
message = "Want to generate output file #{name}, but a file with that name has already been written by this process. Your SON structure contains 2+ different classes with the same name"
|
546
|
+
error_and_exit(message)
|
547
|
+
end
|
548
|
+
end
|
549
|
+
|
550
|
+
filename = file_path + File::SEPARATOR + name
|
440
551
|
contents = out[:contents]
|
441
552
|
unless force_file
|
442
553
|
error_and_exit "Want to generate output file #{name}, but that file already exists" if File.exists?(name)
|
443
554
|
end
|
444
|
-
File.open(
|
555
|
+
File.open(filename, "w+") do |f|
|
445
556
|
f.puts contents
|
446
557
|
end
|
558
|
+
written_file_names << name
|
447
559
|
puts "Wrote out file #{name}"
|
448
560
|
end
|
449
561
|
|
data/test/test_class_from_son.rb
CHANGED
@@ -19,7 +19,7 @@ class TestEx < Test::Unit::TestCase
|
|
19
19
|
|
20
20
|
address_filename = "address.rb"
|
21
21
|
top_level_filename = "generated_from_json.rb"
|
22
|
-
phonenumbers_filename = "
|
22
|
+
phonenumbers_filename = "phone_numbers.rb"
|
23
23
|
|
24
24
|
expected_address = File.readlines(address_filename).join.chomp # trim off any trailing whitespace (irrelevent for this test)
|
25
25
|
expected_example = File.readlines(top_level_filename).join.chomp # trim off any trailing whitespace (irrelevent for this test)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: class_from_son
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Richard Morrisby
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-07-06 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: This gem will attempt to generate code of a class of an object representing
|
14
14
|
the contents of a Serialised-Object-Notation (SON) string (or file). E.g. it will
|