jsoning 0.7.0 → 0.8.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
  SHA1:
3
- metadata.gz: 5b677bf0eef2f3f5ec7b07e6132e038ab33e4111
4
- data.tar.gz: b7db25000fd4b3473d178b7cbaf488a7412d52e3
3
+ metadata.gz: fd577237f0bce4d654d6b0294a0d30ec12b3f060
4
+ data.tar.gz: 42951f8a06781a5565b61d417730dbb44411c06e
5
5
  SHA512:
6
- metadata.gz: 4ebff10b0fa858c2c787d1f5c14f658fd272e4e99fd7d74880772e23da97a6001e4780a98418a23ce101f329a94780fc71c21f12b2bf5769f8134a4fe1073417
7
- data.tar.gz: ca07af734f5508bb36218ae69c601ee636e8f8d379b9e08666ffacb154439ec530cda86c84a795d8c8db8426549eb52aa585e61ca53009cbd2cc2b5dd860afba
6
+ metadata.gz: 132eeb81dbe3fb5e5e33045d1c83fa00bb27cb0facfb3509ba9b0613a71af42fb55b52f61e0d2ecd0af8e3c5fe73b6dc25248dcc08986e940f1531129eebe246
7
+ data.tar.gz: 64eb70554da8b32ad0066e9993c2dbcd634b1826716c3fe77dee45b802477352df6532e4c330c8a95bd9233069e78a1f56b8fc64df88947774de7bab381b33a4
data/README.md CHANGED
@@ -292,13 +292,21 @@ expect(Jsoning.generate(book, hash: true, version: :v1)).to eq({"name"=>"Harry P
292
292
  expect(Jsoning.generate(book, hash: true, version: :v2)).to eq({"book_name"=>"Harry Potter"})
293
293
  ```
294
294
 
295
- We can also generate the whole user json/hash, too:
295
+ Notice that we can use `inherits` to save ourself from writing keys that have been defined somewhere when
296
+ we do versioning:
296
297
 
297
298
  ```ruby
298
- json = Jsoning.generate(user, version: :v1)
299
- expect(JSON.parse(json)).to eq({"name"=>"Adam Baihaqi", "upcase_name"=>"ADAM BAIHAQI", "years_old"=>21, "gender"=>"male", "books"=>[{"name"=>"Quiet: The Power of Introvert"}, {"name"=>"Harry Potter and the Half-Blood Prince"}], "degree_detail"=>nil, "registered_at"=>"2015-11-01T14:41:09+0000"})
300
- json = Jsoning.generate(user, version: :v2)
301
- expect(JSON.parse(json)).to eq({"name"=>"Adam Baihaqi", "upcase_name"=>"ADAM BAIHAQI", "years_old"=>21, "gender"=>"male", "books"=>[{"book_name"=>"Quiet: The Power of Introvert"}, {"book_name"=>"Harry Potter and the Half-Blood Prince"}], "degree_detail"=>nil, "registered_at"=>"2015-11-01T14:41:09+0000"})
299
+ Jsoning.for(My::User) do
300
+ version :v2 do
301
+ inherits :name, :age, :gender, :taken_degree, :books
302
+ key :upcase_name, from: :name, value: proc { |name| name.upcase }
303
+ end
304
+
305
+ version :v3 do
306
+ inherits :name, :age, :gender, :taken_degree, :books
307
+ inherits :upcase_name, from: :v2
308
+ end
309
+ end
302
310
  ```
303
311
 
304
312
  If for when generating object, the requested versioning is undefined, the default version will be used.
@@ -337,6 +345,10 @@ If for when generating object, the requested versioning is undefined, the defaul
337
345
 
338
346
  1. Add value post-processor
339
347
 
348
+ == Version 0.8.0
349
+
350
+ 1. Add `inherits` allowing versioned result to inherits key from default namespace
351
+
340
352
  ## License
341
353
 
342
354
  The gem is proudly available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/lib/jsoning.rb CHANGED
@@ -16,7 +16,7 @@ module Jsoning
16
16
  module_function
17
17
 
18
18
  # returns a protocol, or create one if none exists
19
- def protocol_for(klass)
19
+ def protocol_for_or_create(klass)
20
20
  protocol = PROTOCOLS[klass.to_s]
21
21
  if protocol.nil?
22
22
  protocol = Jsoning::Protocol.new(klass)
@@ -39,7 +39,7 @@ module Jsoning
39
39
 
40
40
  # define the protocol
41
41
  def for(klass, &block)
42
- Jsoning::ForDsl.new(protocol_for(klass)).instance_eval(&block)
42
+ Jsoning::ForDsl.new(protocol_for_or_create(klass)).instance_eval(&block)
43
43
  end
44
44
 
45
45
  # generate the json document
@@ -91,7 +91,7 @@ module Jsoning
91
91
 
92
92
  begin
93
93
  ::Time
94
- self.add_type Time, processor: proc { |time| time.strftime("%FT%T%z") }
94
+ self.add_type ::Time, processor: proc { |time| time.strftime("%FT%T%z") }
95
95
  rescue
96
96
  end
97
97
 
@@ -106,14 +106,14 @@ module Jsoning
106
106
 
107
107
  begin
108
108
  ::DateTime
109
- self.add_type DateTime, processor: proc { |date| date.strftime("%FT%T%z") }
109
+ self.add_type ::DateTime, processor: proc { |date| date.strftime("%FT%T%z") }
110
110
  rescue => e
111
111
  # nothing, don't add
112
112
  end
113
113
 
114
114
  begin
115
115
  ::Date
116
- self.add_type Date, processor: proc { |date| date.strftime("%FT%T%z") }
116
+ self.add_type ::Date, processor: proc { |date| date.strftime("%FT%T%z") }
117
117
  rescue
118
118
  # nothing, don't add
119
119
  end
@@ -7,6 +7,35 @@ class Jsoning::ForDsl
7
7
  @protocol = protocol
8
8
  end
9
9
 
10
+ # inherits can happen inside version block
11
+ # it allows version to inherit specific key from parents
12
+ def inherits(*args)
13
+ fail 'Must be inside version block' unless current_version_object
14
+ all_keys = []
15
+ options = {}
16
+
17
+ args.each do |arg|
18
+ if arg.is_a?(String) || arg.is_a?(Symbol)
19
+ all_keys << arg
20
+ elsif arg.is_a?(Hash)
21
+ options = arg
22
+ end
23
+ end
24
+
25
+ current_version = self.current_version_object
26
+ if options[:from] || options['from']
27
+ parent_version = current_version.protocol.get_version(options[:from] || options['from'])
28
+ else
29
+ parent_version = current_version.protocol.get_version(:default)
30
+ end
31
+
32
+ all_keys.each do |key_name|
33
+ mapper = parent_version.mapper_for(key_name)
34
+ current_version.add_mapper(mapper)
35
+ end
36
+ all_keys
37
+ end
38
+
10
39
  # specify the version under which key will be executed
11
40
  def version(version_name)
12
41
  @@mutex.synchronize do
@@ -20,6 +49,7 @@ class Jsoning::ForDsl
20
49
 
21
50
  self.current_version_object = version
22
51
  yield
52
+ self.current_version_object = nil
23
53
  end
24
54
  end
25
55
 
@@ -39,7 +39,7 @@ class Jsoning::Mapper
39
39
 
40
40
  if object.respond_to?(parallel_variable)
41
41
  parallel_val = object.send(parallel_variable)
42
- target_value = deep_parse(parallel_val, requested_version_name)
42
+ target_value = parallel_val
43
43
  end
44
44
 
45
45
  if target_value.nil?
@@ -49,22 +49,23 @@ class Jsoning::Mapper
49
49
  end
50
50
  end
51
51
 
52
- extracted_value = deep_parse(target_value, requested_version_name)
53
-
54
52
  # apply extractor to extracted value, if processor is defined
55
53
  if value_processor
56
- extracted_value = value_processor.(extracted_value)
54
+ target_value = deep_parse(target_value, requested_version_name, false)
55
+ target_value = value_processor.(target_value)
56
+ else
57
+ target_value = deep_parse(target_value, requested_version_name, true)
57
58
  end
58
59
 
59
- target_hash[name] = extracted_value
60
+ target_hash[name] = target_value
60
61
  end
61
62
 
62
63
  def default_value(version_name = self.version.version_name)
63
64
  if @default_value
64
65
  if @default_value.is_a?(Proc)
65
- return deep_parse(@default_value.(), version_name)
66
+ return deep_parse(@default_value.(), version_name, true)
66
67
  else
67
- return deep_parse(@default_value, version_name)
68
+ return deep_parse(@default_value, version_name, true)
68
69
  end
69
70
  else
70
71
  nil
@@ -72,29 +73,40 @@ class Jsoning::Mapper
72
73
  end
73
74
 
74
75
  private
75
- def deep_parse(object, version_name)
76
+ def deep_parse(object, version_name, run_value_extractor)
76
77
  parsed_data = nil
77
78
 
78
79
  value_extractor = Jsoning::TYPE_EXTENSIONS[object.class.to_s]
79
- if value_extractor # is defined
80
+ if value_extractor && run_value_extractor # is defined
80
81
  parsed_data = value_extractor.(object)
81
82
  else
82
83
  if object.is_a?(Array)
83
84
  parsed_data = []
84
85
  object.each do |each_obj|
85
- parsed_data << deep_parse(each_obj, version_name)
86
+ parsed_data << deep_parse(each_obj, version_name, run_value_extractor)
86
87
  end
87
88
  elsif object.is_a?(Hash)
88
89
  parsed_data = {}
89
90
  object.each do |obj_key_name, obj_val|
90
- parsed_data[obj_key_name] = deep_parse(obj_val, version_name)
91
+ parsed_data[obj_key_name] = deep_parse(obj_val, version_name, run_value_extractor)
91
92
  end
92
93
  elsif object.is_a?(Integer) || object.is_a?(Float) || object.is_a?(String) ||
93
94
  object.is_a?(TrueClass) || object.is_a?(FalseClass) || object.is_a?(NilClass)
94
95
  parsed_data = object
95
96
  else
96
- protocol = Jsoning.protocol_for!(object.class)
97
- parsed_data = protocol.retrieve_values_from(object, {version: version_name})
97
+ if run_value_extractor
98
+ protocol = Jsoning.protocol_for!(object.class)
99
+ parsed_data = protocol.retrieve_values_from(object, {version: version_name})
100
+ else
101
+ # if value extractor is false, don't raise error if protocol is undefined.
102
+ # value processor is exactly way for user to customly extract data in-line
103
+ protocol = Jsoning::PROTOCOLS[object.class]
104
+ if protocol
105
+ parsed_data = protocol.retrieve_values_from(object, {version: version_name})
106
+ else
107
+ parsed_data = object
108
+ end
109
+ end
98
110
  end
99
111
  end
100
112
 
@@ -1,3 +1,3 @@
1
1
  module Jsoning
2
- VERSION = "0.7.0"
2
+ VERSION = "0.8.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jsoning
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Pahlevi