class_from_son 0.1.0 → 0.1.5

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
- SHA1:
3
- metadata.gz: 53b0a1472f3977c2b06e85680263efdd69178894
4
- data.tar.gz: 70b7f897adb5ee1b4ead08b90517eb2d1d412dad
2
+ SHA256:
3
+ metadata.gz: f413bc7bc0f742bf3ac5f2cee734a668edf7d53f0a2e10718f852fdcce4cc901
4
+ data.tar.gz: 87ca04dc961b84b5fdb1779643e52d548e6c4f84899870c9f297802d498ce196
5
5
  SHA512:
6
- metadata.gz: da824ddb560f2d64d476b3602d6e8c24c59f62ee62a367bf2b532813877d5151fdc45daae57ccc90aea77b3e9acf04054c1218e6fa5b60a4da284ba8ae9728f8
7
- data.tar.gz: 640658471d76f8fa525f8057d6dc7a7159a56c093f498f165d1f570f9da6c0dce11f1e9c32ac09d0b016a2dcc2fd5d6a9575c58a481a3aae17a0ac9145b2173e
6
+ metadata.gz: aeff2562e7f122804a323348eebc4cfa6a3cadb89e3e5f4a9bb755d62e0f9890b07268fb483b71f4b245bf575300de88599903fdeb8c7ff4906bff96323fc936
7
+ data.tar.gz: 941bb7fbd059e1634d5dfd6fd5628b7e913c99883610b4e7a30c13ea29bd8d2610f766bd818ce53fee931e3e19167d1b61163fab9234151bdd09cc102664e15b
@@ -7,19 +7,33 @@ If the SON looks to have a nested object structure (e.g. a Contact object looks
7
7
  Limitations :
8
8
 
9
9
  SON : will only process JSON
10
- Code : will only generate Ruby or Java
10
+ Code : will only generate Ruby or Java (to generate Java using Lombok, use the :java_lombok symbol)
11
11
 
12
- Usage : require the gem, then invoke as follows :
12
+ Usage : require the gem, then invoke
13
13
 
14
- ClassFromSON.generate_from_file :ruby, a_file.json
14
+ ```
15
+ require 'class_from_son'
16
+
17
+ ClassFromSON.generate_from_file :ruby, "a_file.json"
15
18
 
16
19
  or
17
20
 
18
21
  ClassFromSON.generate :ruby, my_json_string, :json
22
+ ```
23
+
24
+ or from the command line :
19
25
 
26
+ ```
27
+ ruby -e "require 'class_from_son'; ClassFromSON.generate_from_file :ruby, 'a_file.json'"
28
+
29
+ or
30
+
31
+ ruby -e "require 'class_from_son'; ClassFromSON.generate :ruby, my_json_string, :json"
32
+ ```
20
33
 
21
34
  Method parameter explanations :
22
35
 
36
+ ```
23
37
  # Will generate classes from a SON file
24
38
  # Regardless of whether or not files are written, this will return an array of hashes; each hash represents a file, with two keys : :name for filename (without extension), and :contents for file contents
25
39
  #
@@ -29,9 +43,9 @@ Method parameter explanations :
29
43
  # make_file flag defaults to true; set to false if you do not want files to be created by this method
30
44
  # force_file flag is false; set to true if you wish to overwrite matching destination files (use with caution!)
31
45
  def ClassFromSON.generate_from_file(dest_lang, file, source_lang, make_file = true, force_file = false)
46
+ ```
32
47
 
33
-
34
-
48
+ ```
35
49
  # Will generate classes from a SON string
36
50
  # Regardless of whether or not files are written, this will return an array of hashes; each hash represents a file, with two keys : :name for filename (without extension), and :contents for file contents
37
51
  #
@@ -41,3 +55,4 @@ def ClassFromSON.generate_from_file(dest_lang, file, source_lang, make_file = tr
41
55
  # make_file flag defaults to true; set to false if you do not want files to be created by this method
42
56
  # force_file flag is false; set to true if you wish to overwrite matching destination files (use with caution!)
43
57
  def ClassFromSON.generate(dest_lang, source, source_lang, make_file = true, force_file = false)
58
+ ```
@@ -1,11 +1,11 @@
1
1
  require "json"
2
- require "more-ruby"
2
+ require "more_ruby"
3
3
 
4
4
  # A utility to convert an input file of string-object notation, e.g. JSON, XML, YAML, and generate code that looks like a class of your desired language
5
5
 
6
6
  class ClassFromSON
7
7
 
8
- @@target_languages = [:java, :ruby]
8
+ @@target_languages = [:java, :java_lombok, :ruby]
9
9
  @@input_modes = [:json]
10
10
 
11
11
  def error(message)
@@ -55,7 +55,7 @@ class ClassFromSON
55
55
  # Translate "Fixnum" into the desired output language
56
56
  def convert_fixnum_to_type
57
57
  case @language
58
- when :java
58
+ when :java, :java_lombok
59
59
  return "int"
60
60
  else
61
61
  error_and_exit "Could not convert to output language #{@language}"
@@ -65,7 +65,7 @@ class ClassFromSON
65
65
  # Translate "Fixnum" into the desired output language
66
66
  def convert_float_to_type
67
67
  case @language
68
- when :java
68
+ when :java, :java_lombok
69
69
  return "float"
70
70
  else
71
71
  error_and_exit "Could not convert to output language #{@language}"
@@ -75,7 +75,7 @@ class ClassFromSON
75
75
  # Translate "Fixnum" into the desired output language
76
76
  def convert_boolean_to_type
77
77
  case @language
78
- when :java
78
+ when :java, :java_lombok
79
79
  return "boolean"
80
80
  else
81
81
  error_and_exit "Could not convert to output language #{@language}"
@@ -85,7 +85,7 @@ class ClassFromSON
85
85
  # Translate "String" into the desired output language
86
86
  def convert_string_to_type
87
87
  case @language
88
- when :java
88
+ when :java, :java_lombok
89
89
  return "String"
90
90
  else
91
91
  error_and_exit "Could not convert to output language #{@language}"
@@ -97,7 +97,7 @@ class ClassFromSON
97
97
  def convert_array_to_type(value_types)
98
98
  error_and_exit "Detected an array, but could not determine the type of its children; found #{value_types.size} possibilities" unless value_types.size == 1
99
99
  case @language
100
- when :java
100
+ when :java, :java_lombok
101
101
  return "List<#{convert_ruby_type_to_type(value_types[0])}>"
102
102
  else
103
103
  error_and_exit "Could not convert to output language #{@language}"
@@ -109,7 +109,7 @@ class ClassFromSON
109
109
  def convert_hash_to_type(value_types)
110
110
  error_and_exit "Detected a hash, but could not determine the type of its keys and values; found #{value_types.size} possibilities" unless value_types.size == 2
111
111
  case @language
112
- when :java
112
+ when :java, :java_lombok
113
113
  return "HashMap<#{convert_ruby_type_to_type(value_types[0])}, #{convert_ruby_type_to_type(value_types[1])}>"
114
114
  else
115
115
  error_and_exit "Could not convert to output language #{@language}"
@@ -119,7 +119,7 @@ class ClassFromSON
119
119
  # Returns code representing the start of the class
120
120
  def convert_custom_class_type(type)
121
121
  case @language
122
- when :java, :ruby
122
+ when :java, :java_lombok, :ruby
123
123
  return type.capitalize_first_letter_only
124
124
  else
125
125
  error_and_exit "Could not convert to output language #{@language}"
@@ -128,7 +128,7 @@ class ClassFromSON
128
128
 
129
129
  def generate_top_level_name
130
130
  case @language
131
- when :java
131
+ when :java, :java_lombok
132
132
  return "generatedFrom#{@mode.capitalize}"
133
133
  when :ruby
134
134
  return "generated_from_#{@mode}"
@@ -140,7 +140,7 @@ class ClassFromSON
140
140
  # Returns an appropriately-formatted classname for the given name
141
141
  def generate_classname(name)
142
142
  case @language
143
- when :java, :ruby
143
+ when :java, :java_lombok, :ruby
144
144
  return name.capitalize_first_letter_only
145
145
  else
146
146
  error_and_exit "Could not convert to output language #{@language}"
@@ -150,10 +150,10 @@ class ClassFromSON
150
150
  # Returns an appropriately-formatted filename for the given name
151
151
  def generate_filename(name)
152
152
  case @language
153
- when :java
153
+ when :java, :java_lombok
154
154
  return name.capitalize_first_letter_only + @extension
155
155
  when :ruby
156
- return name.downcase + @extension # TODO convert camelcase to underbarised case
156
+ return name.snakecase + @extension
157
157
  else
158
158
  error_and_exit "Could not convert to output language #{@language}"
159
159
  end
@@ -161,7 +161,7 @@ class ClassFromSON
161
161
 
162
162
  def set_file_extension_for_language
163
163
  case @language
164
- when :java
164
+ when :java, :java_lombok
165
165
  @extension = ".java"
166
166
  when :ruby
167
167
  @extension = ".rb"
@@ -173,8 +173,31 @@ class ClassFromSON
173
173
  # Returns code representing the start of the class
174
174
  def generate_class_start(name)
175
175
  case @language
176
- when :java
177
- start = "public class #{convert_custom_class_type(name)} {"
176
+ when :java, :java_lombok
177
+ start = <<-START
178
+
179
+ import com.fasterxml.jackson.annotation.JsonProperty;
180
+
181
+ public class #{convert_custom_class_type(name)} {
182
+ START
183
+ when :java_lombok # TODO
184
+ start = <<-START
185
+
186
+ import com.fasterxml.jackson.annotation.JsonProperty;
187
+ import lombok.AllArgsConstructor;
188
+ import lombok.Builder;
189
+ import lombok.Getter;
190
+ import lombok.NoArgsConstructor;
191
+ import lombok.Setter;
192
+
193
+ @JsonInclude(Include.NON_NULL)
194
+ @NoArgsConstructor // Need @NoArgsConstructor for JSON deserialisation
195
+ @AllArgsConstructor // Need @AllArgsConstructor for @Builder
196
+ @Builder
197
+ @Getter
198
+ @Setter
199
+ public class #{convert_custom_class_type(name)} {
200
+ START
178
201
  when :ruby
179
202
  start = "class #{convert_custom_class_type(name)}"
180
203
  else
@@ -186,7 +209,7 @@ class ClassFromSON
186
209
  # Returns code representing the end of the class
187
210
  def generate_class_end
188
211
  case @language
189
- when :java
212
+ when :java, :java_lombok
190
213
  class_end = "}"
191
214
  when :ruby
192
215
  class_end = "end"
@@ -199,6 +222,8 @@ class ClassFromSON
199
222
  def generate_getter_and_setter(type, name)
200
223
  lines = []
201
224
  case @language
225
+ when :java_lombok
226
+ # do nothing - Lombok's raison d'etre is to avoid getters & setters
202
227
  when :java
203
228
  class_name = convert_custom_class_type(name)
204
229
  lines << "\t"
@@ -218,7 +243,7 @@ class ClassFromSON
218
243
  # Returns code representing each of the supplied attributes
219
244
  def generate_code_from_attributes(attributes)
220
245
  case @language
221
- when :java
246
+ when :java, :java_lombok
222
247
  return generate_java_code_from_attributes(attributes)
223
248
  when :ruby
224
249
  return generate_ruby_code_from_attributes(attributes)
@@ -232,7 +257,14 @@ class ClassFromSON
232
257
  code = []
233
258
  # Instance variables
234
259
  attributes.each do |att|
235
- code << "\tpublic #{convert_ruby_type_to_type(att[:type], att[:value_types])} #{att[:name]};"
260
+ if att[:name].include? "_"
261
+ snakecase_name = att[:name]
262
+ camelcase_name = att[:name].camelcase
263
+ code << "\t@JsonProperty(\"#{snakecase_name}\")"
264
+ code << "\tprivate #{convert_ruby_type_to_type(att[:type], att[:value_types])} #{camelcase_name};"
265
+ else
266
+ code << "\tprivate #{convert_ruby_type_to_type(att[:type], att[:value_types])} #{att[:name]};"
267
+ end
236
268
  end
237
269
 
238
270
  #TODO constructor
@@ -372,10 +404,14 @@ class ClassFromSON
372
404
  error_and_exit "Cannot parse input language #{@mode}; can only parse #{@@input_modes.join(", ")}"
373
405
  end
374
406
 
407
+ # TODO other input languages, e.g. XML, YAML
375
408
  case @mode
376
409
  when :json
377
- hash = JSON.parse(source)
378
- # TODO other input languages, e.g. XML, YAML
410
+ begin
411
+ hash = JSON.parse(source)
412
+ rescue JSON::ParserError => e
413
+ error_and_exit "Could not parse supplied string as JSON. Error message : #{e.message}"
414
+ end
379
415
  else
380
416
  error_and_exit "Cannot parse mode #{@mode}"
381
417
  end
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.1.0
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Richard Morrisby
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-07-03 00:00:00.000000000 Z
11
+ date: 2020-08-20 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
@@ -16,21 +16,12 @@ description: This gem will attempt to generate code of a class of an object repr
16
16
  email: rmorrisby@gmail.com
17
17
  executables: []
18
18
  extensions: []
19
- extra_rdoc_files: []
19
+ extra_rdoc_files:
20
+ - README.md
20
21
  files:
21
- - LICENCE.txt
22
- - README.txt
23
- - build.rb
24
- - class_from_son.gemspec
22
+ - README.md
25
23
  - lib/class_from_SON.rb
26
- - test/Address.java
27
- - test/GeneratedFromJson.java
28
- - test/PhoneNumbers.java
29
- - test/address.rb
30
- - test/generated_from_json.rb
31
- - test/phonenumbers.rb
32
24
  - test/test_class_from_son.rb
33
- - test/testjson.json
34
25
  homepage: https://rubygems.org/gems/class_from_son
35
26
  licenses:
36
27
  - MIT
@@ -50,10 +41,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
50
41
  - !ruby/object:Gem::Version
51
42
  version: '0'
52
43
  requirements: []
53
- rubyforge_project:
54
- rubygems_version: 2.6.7
44
+ rubygems_version: 3.0.3
55
45
  signing_key:
56
46
  specification_version: 4
57
- summary: Generates classes from SON (e.g. JSON)
47
+ summary: Generates classes from Serialised-Object-Notation (e.g. JSON)
58
48
  test_files:
59
49
  - test/test_class_from_son.rb
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2016 Richard Morrisby
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
data/build.rb DELETED
@@ -1,51 +0,0 @@
1
- # Simple build script
2
- # Deletes the existing gem file (if present)
3
- # Uninstalls the gem
4
- # Builds the gem
5
- # Installs the new gem
6
-
7
- # Note : when calling system (or backticks, etc.) th enew process starts at the system default, not the current working directory.
8
- # Therefore we need to use a syntax of : system "cd #{gem_dir} && #{i_cmd}"
9
-
10
- # Run from this directory!
11
-
12
- gem_dir = Dir.getwd
13
-
14
- # Delete existing .gem files in the dir
15
-
16
- gemfiles = Dir.entries(gem_dir).collect {|q| q if q =~ /.gem$/}.compact
17
-
18
- gemfiles.each do |q|
19
- File.delete q
20
- puts "Deleted #{q}"
21
- end
22
-
23
- gemfiles = Dir.entries(gem_dir).collect {|q| q if q =~ /.gem$/}.compact
24
- raise "Gem has not been deleted" unless gemfiles.size == 0
25
-
26
- # Uninstall, build, install
27
- gemspecs = Dir.entries(gem_dir).collect {|q| q if q =~ /.gemspec$/}.compact
28
-
29
- raise "Did not find a .gemspec in #{gem_dir}" if gemspecs.size < 1
30
- raise "Found more than one .gemspec in #{gem_dir}" if gemspecs.size > 1
31
-
32
- gemspec = gemspecs[0]
33
-
34
- gemname = File.basename(gemspec, File.extname(gemspec))
35
-
36
- u_cmd = "gem uninstall #{gemname}"
37
- system u_cmd
38
-
39
- b_cmd = "gem build #{gemspec}"
40
- system "cd #{gem_dir} && #{b_cmd}"
41
-
42
- gemfiles = Dir.entries(gem_dir).collect {|q| q if q =~ /.gem$/}.compact
43
- raise "Gem was not built" unless gemfiles.size == 1
44
-
45
- gemfile = gemfiles[0]
46
- raise "Gem file is not for the expected gem, expected a #{gemname} gem but found #{gemfile}" unless gemfile =~ /^#{gemname}/
47
-
48
- i_cmd = "gem install #{gemfile}"
49
- system "cd #{gem_dir} && #{i_cmd}"
50
-
51
- puts "Gem #{gemname} built & installed"
@@ -1,15 +0,0 @@
1
- Gem::Specification.new do |s|
2
- s.name = 'class_from_son'
3
- s.version = '0.1.0'
4
- s.licenses = ['MIT']
5
- s.summary = "Generates classes from SON (e.g. JSON)"
6
- s.description = "This gem will attempt to generate code of a class of an object representing the contents of a Serialised-Object-Notation (SON) string (or file). E.g. it will generate code of a object's class from some JSON."
7
- s.authors = ["Richard Morrisby"]
8
- s.email = 'rmorrisby@gmail.com'
9
- s.files = ["lib/class_from_SON.rb"]
10
- s.homepage = 'https://rubygems.org/gems/class_from_son'
11
- s.required_ruby_version = '>=1.9'
12
- s.files = Dir['**/**']
13
- s.test_files = Dir["test/test*.rb"]
14
- s.has_rdoc = true
15
- end
@@ -1,38 +0,0 @@
1
- public class Address {
2
- public String streetAddress;
3
- public String city;
4
- public String state;
5
- public String postalCode;
6
-
7
- public String getStreetAddress() {
8
- return streetAddress;
9
- }
10
-
11
- public void setStreetAddress(String streetAddress) {
12
- this.streetAddress = streetAddress;
13
- }
14
-
15
- public String getCity() {
16
- return city;
17
- }
18
-
19
- public void setCity(String city) {
20
- this.city = city;
21
- }
22
-
23
- public String getState() {
24
- return state;
25
- }
26
-
27
- public void setState(String state) {
28
- this.state = state;
29
- }
30
-
31
- public String getPostalCode() {
32
- return postalCode;
33
- }
34
-
35
- public void setPostalCode(String postalCode) {
36
- this.postalCode = postalCode;
37
- }
38
- }
@@ -1,74 +0,0 @@
1
- public class GeneratedFromJson {
2
- public String firstName;
3
- public String lastName;
4
- public boolean isAlive;
5
- public int age;
6
- public Address address;
7
- public List<PhoneNumbers> phoneNumbers;
8
- public List<String> children;
9
- public String spouse;
10
-
11
- public String getFirstName() {
12
- return firstName;
13
- }
14
-
15
- public void setFirstName(String firstName) {
16
- this.firstName = firstName;
17
- }
18
-
19
- public String getLastName() {
20
- return lastName;
21
- }
22
-
23
- public void setLastName(String lastName) {
24
- this.lastName = lastName;
25
- }
26
-
27
- public boolean getIsAlive() {
28
- return isAlive;
29
- }
30
-
31
- public void setIsAlive(boolean isAlive) {
32
- this.isAlive = isAlive;
33
- }
34
-
35
- public int getAge() {
36
- return age;
37
- }
38
-
39
- public void setAge(int age) {
40
- this.age = age;
41
- }
42
-
43
- public Address getAddress() {
44
- return address;
45
- }
46
-
47
- public void setAddress(Address address) {
48
- this.address = address;
49
- }
50
-
51
- public List<PhoneNumbers> getPhoneNumbers() {
52
- return phoneNumbers;
53
- }
54
-
55
- public void setPhoneNumbers(List<PhoneNumbers> phoneNumbers) {
56
- this.phoneNumbers = phoneNumbers;
57
- }
58
-
59
- public List<String> getChildren() {
60
- return children;
61
- }
62
-
63
- public void setChildren(List<String> children) {
64
- this.children = children;
65
- }
66
-
67
- public String getSpouse() {
68
- return spouse;
69
- }
70
-
71
- public void setSpouse(String spouse) {
72
- this.spouse = spouse;
73
- }
74
- }
@@ -1,20 +0,0 @@
1
- public class PhoneNumbers {
2
- public String type;
3
- public String number;
4
-
5
- public String getType() {
6
- return type;
7
- }
8
-
9
- public void setType(String type) {
10
- this.type = type;
11
- }
12
-
13
- public String getNumber() {
14
- return number;
15
- }
16
-
17
- public void setNumber(String number) {
18
- this.number = number;
19
- }
20
- }
@@ -1,13 +0,0 @@
1
- class Address
2
- attr_accessor :streetAddress
3
- attr_accessor :city
4
- attr_accessor :state
5
- attr_accessor :postalCode
6
-
7
- def initialize(streetAddress, city, state, postalCode)
8
- @streetAddress = streetAddress
9
- @city = city
10
- @state = state
11
- @postalCode = postalCode
12
- end
13
- end
@@ -1,21 +0,0 @@
1
- class Generated_from_json
2
- attr_accessor :firstName
3
- attr_accessor :lastName
4
- attr_accessor :isAlive
5
- attr_accessor :age
6
- attr_accessor :address
7
- attr_accessor :phoneNumbers
8
- attr_accessor :children
9
- attr_accessor :spouse
10
-
11
- def initialize(firstName, lastName, isAlive, age, address, phoneNumbers, children, spouse)
12
- @firstName = firstName
13
- @lastName = lastName
14
- @isAlive = isAlive
15
- @age = age
16
- @address = address
17
- @phoneNumbers = phoneNumbers
18
- @children = children
19
- @spouse = spouse
20
- end
21
- end
@@ -1,9 +0,0 @@
1
- class PhoneNumbers
2
- attr_accessor :type
3
- attr_accessor :number
4
-
5
- def initialize(type, number)
6
- @type = type
7
- @number = number
8
- end
9
- end
@@ -1,28 +0,0 @@
1
- {
2
- "firstName": "John",
3
- "lastName": "Smith",
4
- "isAlive": true,
5
- "age": 25,
6
- "address": {
7
- "streetAddress": "21 2nd Street",
8
- "city": "New York",
9
- "state": "NY",
10
- "postalCode": "10021-3100"
11
- },
12
- "phoneNumbers": [
13
- {
14
- "type": "home",
15
- "number": "212 555-1234"
16
- },
17
- {
18
- "type": "office",
19
- "number": "646 555-4567"
20
- },
21
- {
22
- "type": "mobile",
23
- "number": "123 456-7890"
24
- }
25
- ],
26
- "children": [],
27
- "spouse": null
28
- }