objectifier 0.2.0 → 0.3.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: a71bbcefb888b422bb26aaa6a066f0452b4eaa60
4
- data.tar.gz: 93a3dfef0ad8fc02ec4d6f60e1a03eaa03c53a78
3
+ metadata.gz: 815817635baa45e7a1ddf70cfbecd860b2b33e64
4
+ data.tar.gz: 64be5d2076c97859304f5ab810849ec98f08c1f2
5
5
  SHA512:
6
- metadata.gz: a6012c2e53a65516f6b84b718c7be7976ef13a0dba305f8bed87d4dbc6c4634a1c40fa2d809ec793156475cea69f3575d6beae751534c347ce2f6ea746ed68c1
7
- data.tar.gz: 480c670c84094cc87cd2753e7deeb7e58c6468bc15036b5e460fce4ba8aa3c6ecfa0fcecb413991b6bed3265d0655fb5c27b78d2bd394d5b5bc34064a196126d
6
+ metadata.gz: 584bd0a3fa9f96bb636acd0c7318bcdd276762e010f00f266a951596599a58b47e038a213266f02e0527a912cfc792756be4909af797837f691b44865166460b
7
+ data.tar.gz: 1d16c9f434d6167cd271cbd66a962af5763a705fbdad55ee0c2cda00a18c6a8a9b3c40bef5c62fb9d6fa4b25e2727aa55cb939e40f6987fbf4891781babf34d6
data/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Change Log
2
2
 
3
+ ## UNRELEASED
4
+
5
+
6
+ ## 0.3.0 2017-03-07
7
+
8
+ ### Added
9
+ Tests for built-in transformer functions
10
+
11
+ ### Changed
12
+ Floating point transformer to not silently convert strings to zero
13
+
14
+ ### Changed
15
+ Transformer type keys to be symbols instead of constants
16
+
17
+
3
18
  ## 0.2.0 2016-10-16
4
19
 
5
20
  ### Added
@@ -9,6 +24,7 @@ Change Log file.
9
24
  Gem dependencies fixed for development and runtime to only require
10
25
  MRI 1.9.3 and later.
11
26
 
27
+
12
28
  ## 0.1.0 2016-10-13
13
29
 
14
30
  ### Added
data/README.md CHANGED
@@ -1,5 +1,6 @@
1
1
  # Objectifier
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/objectifier.svg)](https://badge.fury.io/rb/objectifier)
3
4
  [![Build Status](https://travis-ci.org/wiggly/objectifier.svg?branch=master)](https://travis-ci.org/wiggly/objectifier)
4
5
 
5
6
  De-serialise plain hashes into objects.
@@ -31,27 +32,27 @@ Create custom transformers, create an objectifier and use it to de-serialise has
31
32
  ```
32
33
  require 'objectifier'
33
34
  require 'money'
34
-
35
+
35
36
  # Add a custom tranformer for Money values
36
37
  Objectifier.factories.add_type(
37
- Money,
38
+ :money,
38
39
  ->(name, value) {
39
40
  Objectifier::ValueResult.new(name, Money.new(value["amount"], value["code"]))
40
41
  })
41
42
 
42
43
  # define an objectifier that can be used to de-serialise a given format
43
44
  obj = Objectifier.define do
44
- item :name, type: String, required: false
45
+ item :name, type: :string, required: false
45
46
 
46
- items :accounts, type: Integer
47
+ items :accounts, type: :integer
47
48
 
48
- item :budget, type: Money
49
+ item :budget, type: :money
49
50
 
50
- item :length, type: Integer, required: false
51
+ item :length, type: :integer, required: false
51
52
 
52
53
  map :activity do
53
- item :clicks, type: Integer
54
- item :ctr, type: Float
54
+ item :clicks, type: :integer
55
+ item :ctr, type: :float
55
56
  end
56
57
  end
57
58
 
data/TODO.md ADDED
@@ -0,0 +1,17 @@
1
+ # TODO
2
+
3
+ ## Add nillable items
4
+
5
+ We should allow some things to be nil. The key is present but the value may be nil instead of either fully required or not required.
6
+
7
+ ## Decide whether or not using class names for the transformer types is a good idea (probably not)
8
+
9
+ ## Add Struct in addition to Map types
10
+
11
+ ## Make transformer factory configurable on a per-objectifier basis
12
+
13
+ ## Re-factor so that scalar/array/map also come from transformer factory?
14
+
15
+ ## Add default values for optional items?
16
+
17
+ ## Pass transformer factory through transformers so they can access transformers that exist when de-serializing objects
@@ -0,0 +1,105 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH.unshift('../../lib')
3
+ require 'objectifier'
4
+ require 'pp'
5
+ require 'money'
6
+
7
+ #
8
+ # To run this example you will have to install the 'money' gem
9
+ #
10
+
11
+ #
12
+ # Money objectifier example to show how custom transformers can be created
13
+ # to deserialize types that Objectifier does not know about
14
+ #
15
+ # We have a structure representing a bank account. It contains;
16
+ #
17
+ # id - integer, required
18
+ #
19
+ # balance - money
20
+ #
21
+ # overdraft_limit - money
22
+ #
23
+
24
+ Objectifier.factories.add_type(
25
+ Money,
26
+ ->(name, value) {
27
+ return Objectifier::ErrorResult.err(name, "'value' not present") unless value.key?("amount")
28
+ return Objectifier::ErrorResult.err(name, "'code' not present") unless value.key?("code")
29
+
30
+ Objectifier::ValueResult.new(name, Money.new(value["amount"], value["code"]))
31
+ })
32
+
33
+ obj = Objectifier.define do
34
+ item :id, type: Integer
35
+ item :balance, type: Money
36
+ item :credit_limit, type: Money, required: false
37
+ end
38
+
39
+ puts "Objectifier"
40
+ pp obj
41
+
42
+ # example 1 - complete data
43
+ parameters = {
44
+ "id" => 42,
45
+ "balance" => { "amount" => 100_00, "code" => "CAD" },
46
+ "credit_limit" => { "amount" => (-300_00), "code" => "CAD" },
47
+ }
48
+
49
+ puts "\nComplete Data Result"
50
+ result = obj.call(parameters)
51
+
52
+ if result.success?
53
+ pp result.value
54
+ else
55
+ pp result
56
+ end
57
+
58
+
59
+ # example 2 - required data
60
+ parameters = {
61
+ "id" => 42,
62
+ "balance" => { "amount" => 100_00, "code" => "CAD" },
63
+ }
64
+
65
+ puts "\nRequired Data Result"
66
+ result = obj.call(parameters)
67
+
68
+ if result.success?
69
+ pp result.value
70
+ else
71
+ pp result
72
+ end
73
+
74
+
75
+ # example 3 - missing a required field
76
+ parameters = {
77
+ "id" => 42,
78
+ "credit_limit" => { "amount" => (-300_00), "code" => "CAD" },
79
+ }
80
+
81
+ puts "\nIncomplete Data Result"
82
+ result = obj.call(parameters)
83
+
84
+ if result.success?
85
+ pp result.value
86
+ else
87
+ pp result
88
+ end
89
+
90
+
91
+ # example 4 - malformed data
92
+ parameters = {
93
+ "id" => 42,
94
+ "balance" => { "amount" => 100_00, "code" => "CAD" },
95
+ "credit_limit" => { "code" => "CAD" },
96
+ }
97
+
98
+ puts "\nMalformed Data Result"
99
+ result = obj.call(parameters)
100
+
101
+ if result.success?
102
+ pp result.value
103
+ else
104
+ pp result
105
+ end
@@ -0,0 +1,117 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH.unshift('../../lib')
3
+ require 'objectifier'
4
+ require 'pp'
5
+
6
+ #
7
+ # Simple objectifier example
8
+ #
9
+ # We have a structure representing a person. It contains;
10
+ #
11
+ # name - string, required
12
+ #
13
+ # email - string required
14
+ #
15
+ # dob - string, optional
16
+ # If not present in the data provided it will not be present in the structure returned.
17
+ #
18
+ # location - map, required
19
+ # This map contains lattidue and longitude.
20
+ #
21
+ # It is required since at least one of its children is required.
22
+ #
23
+ #
24
+
25
+ obj = Objectifier.define do
26
+ item :name, type: String
27
+ item :email, type: String
28
+ item :dob, type: String, required: false # TODO: add date/time to the set of builtin transformers
29
+ map :location do
30
+ item :lat, type: Float
31
+ item :lng, type: Float
32
+ end
33
+ end
34
+
35
+ puts "Objectifier"
36
+ pp obj
37
+
38
+ # example 1 - complete data
39
+ parameters = {
40
+ "name" => "John Doe",
41
+ "email" => "john.doe@example.com",
42
+ "dob" => "1964-03-21",
43
+ "location" => {
44
+ "lat" => 51.5077,
45
+ "lng" => -0.1279,
46
+ },
47
+ }
48
+
49
+ puts "\nComplete Data Result"
50
+ result = obj.call(parameters)
51
+
52
+ if result.success?
53
+ pp result.value
54
+ else
55
+ pp result
56
+ end
57
+
58
+
59
+ # example 2 - required data
60
+ parameters = {
61
+ "name" => "John Doe",
62
+ "email" => "john.doe@example.com",
63
+ "location" => {
64
+ "lat" => 51.5077,
65
+ "lng" => -0.1279,
66
+ },
67
+ }
68
+
69
+ puts "\nRequired Data Result"
70
+ result = obj.call(parameters)
71
+
72
+ if result.success?
73
+ pp result.value
74
+ else
75
+ pp result
76
+ end
77
+
78
+
79
+ # example 3 - missing a required field
80
+ parameters = {
81
+ "name" => "John Doe",
82
+ "dob" => "1964-03-21",
83
+ "location" => {
84
+ "lat" => 51.5077,
85
+ "lng" => -0.1279,
86
+ },
87
+ }
88
+
89
+ puts "\nIncomplete Data Result"
90
+ result = obj.call(parameters)
91
+
92
+ if result.success?
93
+ pp result.value
94
+ else
95
+ pp result
96
+ end
97
+
98
+
99
+ # example 4 - malformed data
100
+ parameters = {
101
+ "name" => "John Doe",
102
+ "email" => "john.doe@example.com",
103
+ "dob" => "1964-03-21",
104
+ "location" => {
105
+ "lat" => "fred",
106
+ "lng" => -0.1279,
107
+ },
108
+ }
109
+
110
+ puts "\nMalformed Data Result"
111
+ result = obj.call(parameters)
112
+
113
+ if result.success?
114
+ pp result.value
115
+ else
116
+ pp result
117
+ end
@@ -27,10 +27,6 @@ module Objectifier
27
27
  end
28
28
  end
29
29
 
30
- def pp(indent = "")
31
- "#{indent} #{to_s}"
32
- end
33
-
34
30
  protected
35
31
 
36
32
  def key_present(parameters)
@@ -35,18 +35,6 @@ module Objectifier
35
35
  true
36
36
  end
37
37
 
38
- def pp(indent = "")
39
- next_indent = "#{indent} "
40
- str = "#{indent} #{@scope} {\n"
41
- str << @rules.values.map { |r| r.pp(next_indent) }.join("\n")
42
- str << "\n#{indent}}\n"
43
- str
44
- end
45
-
46
- def to_s
47
- pp("")
48
- end
49
-
50
38
  # examine parameters and return a hash of massaged data or an error results
51
39
  def call(parameters)
52
40
 
@@ -22,15 +22,10 @@ module Objectifier
22
22
  elsif key_present(parameters)
23
23
  transform(key_value(parameters))
24
24
  else
25
- # TODO: this is not a failure...
26
25
  SuccessResult.new(@name)
27
26
  end
28
27
  end
29
28
 
30
- def pp(indent = "")
31
- "#{indent} #{to_s}"
32
- end
33
-
34
29
  def to_s
35
30
  "scalar %s - type: %s - required: %s" % [ @name, @type.to_s, @required.to_s ]
36
31
  end
@@ -4,16 +4,41 @@ module Objectifier
4
4
  class TransformerFactory
5
5
  def initialize
6
6
  @t = Hash.new { |h,k| raise "unknown type #{@type}" }
7
- @t[String] = ->(name, value) { ValueResult.new(name, value.to_s) }
8
- @t[Integer] = ->(name, value) {
7
+
8
+ @t[:boolean] = lambda do |name, value|
9
+ case value
10
+ when true, 'true', 1, '1'
11
+ ValueResult.new(name, true)
12
+ when false, 'false', 0, '0'
13
+ ValueResult.new(name, false)
14
+ else
15
+ ErrorResult.err(name, 'not boolean')
16
+ end
17
+ end
18
+
19
+ @t[:symbol] = ->(name, value) { ValueResult.new(name, value.to_sym) }
20
+
21
+ @t[:string] = ->(name, value) { ValueResult.new(name, value.to_s) }
22
+
23
+ @t[:integer] = lambda do |name, value|
9
24
  begin
10
25
  ValueResult.new(name, Integer(value))
11
26
  rescue => e
12
27
  ErrorResult.err(name, e.message)
13
28
  end
14
- }
15
- @t[Fixnum] = @t[Integer]
16
- @t[Float] = ->(name, value) { ValueResult.new(name, value.to_f) }
29
+ end
30
+
31
+ @t[:fixnum] = @t[:integer]
32
+
33
+ @t[:bignum] = @t[:integer]
34
+
35
+ @t[:float] = lambda do |name, value|
36
+ begin
37
+ ValueResult.new(name, Float(value))
38
+ rescue => e
39
+ ErrorResult.err(name, e.message)
40
+ end
41
+ end
17
42
  end
18
43
 
19
44
  def add_type(type, transformer)
@@ -1,3 +1,3 @@
1
1
  module Objectifier
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: objectifier
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nigel Rantor
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-10-16 00:00:00.000000000 Z
11
+ date: 2017-03-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -152,8 +152,11 @@ files:
152
152
  - LICENSE.txt
153
153
  - README.md
154
154
  - Rakefile
155
+ - TODO.md
155
156
  - bin/console
156
157
  - bin/setup
158
+ - example/money/example.rb
159
+ - example/simple/example.rb
157
160
  - lib/objectifier.rb
158
161
  - lib/objectifier/array_value.rb
159
162
  - lib/objectifier/map_value.rb
@@ -182,7 +185,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
182
185
  version: '0'
183
186
  requirements: []
184
187
  rubyforge_project:
185
- rubygems_version: 2.2.2
188
+ rubygems_version: 2.5.1
186
189
  signing_key:
187
190
  specification_version: 4
188
191
  summary: De-serialize plain hashes into real object graphs