ializer 0.2.0 → 0.7.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: ec12881a7736268012824062951ad8a0d0897687798d1215ef3cf100d1022ab4
4
- data.tar.gz: c0793bd033a02cb2cf675c483e1e265bc80e3745290989c1bb652f006058be82
3
+ metadata.gz: f2edc7490772cdd678feb9fc5f2edc25f9898dfdd85cd1a7010c31ae17c7e907
4
+ data.tar.gz: 22436136f76f5d7ab9be4c9e853f3b971751683d3f08fbe8990b079de543bfef
5
5
  SHA512:
6
- metadata.gz: a314f2d7ee625d7aa92d4756c21a185aa50b152112fc24ea38bba4e56c49de8bdcb032f66bf089f781f0a580bae30078879c6ffaa02fbc869c3c942bb07ef8fd
7
- data.tar.gz: cb08168fb231f03ee45ad1ae429a9a0d79438b546bc4ed71f9132606f522a02af09c70a192a6e61fa8a4c130ac50fd0ded6719ad3857ec147f8fbcd6bad5a93e
6
+ metadata.gz: 1638343079a2be6f0c0ab984255ea8bb4255eb543d2a1b4564fa00f9756f73a8baf04356b39667595b49c6eeb673dab7a762b25ff348e494bd31ef60cf644a46
7
+ data.tar.gz: 1fa34143f0c485ffb25ff602cb98f02f02ea519456ff81ce97ede39890794f35fd53a714e65399a0418275fbc9f4345ccd6c3f4cf1c29df730fc64af4f507a21
data/README.md CHANGED
@@ -13,6 +13,7 @@ A fast serializer/deserializer for Ruby Objects.
13
13
  * [Model Definitions](#model-definitions)
14
14
  * [Serializer Definitions](#serializer-definitions)
15
15
  * [DeSerializer Definitions](#deserializer-definitions)
16
+ * [De/Serializer Configuration](#deserializer-configuration)
16
17
  * [Object Serialization](#object-serialization)
17
18
  * [Object Deserialization](#object-deserialization)
18
19
  * [Attributes](#attributes)
@@ -153,6 +154,26 @@ class CustomerDeSer < De::Ser::Ializer
153
154
  end
154
155
  ```
155
156
 
157
+ ### De/Ser::Ializer Configuration
158
+
159
+ You can override the global config for a specific `Ser::Ializer` or `De::Ser::Ializer` by calling the setup command.
160
+
161
+ **Note:** `setup` must be called at the beginning of the definition otherwise the default config will be used.
162
+
163
+ ```ruby
164
+ class OrderDeSer < De::Ser::Ializer
165
+ setup do |config|
166
+ config.key_transform = :dasherize
167
+ end
168
+
169
+ integer :id
170
+ timestamp :created_at
171
+
172
+ nested :items, deser: OrderItemDeSer, model_class: OrderItem
173
+ nested :customer, deser: CustomerDeSer, model_class: Customer
174
+ end
175
+ ```
176
+
156
177
  ### Sample Object
157
178
 
158
179
  ```ruby
@@ -183,17 +204,17 @@ json_string = OrderDeser.serialize_json(order)
183
204
  ```json
184
205
  {
185
206
  "id": 4,
186
- "created-at": "2019-12-01T00:00:00.000-06:00",
207
+ "created_at": "2019-12-01T00:00:00.000-06:00",
187
208
  "items": [
188
209
  {
189
210
  "name": "Baseball",
190
211
  "decimal": "4.99",
191
- "in-stock": true
212
+ "in_stock": true
192
213
  },
193
214
  {
194
215
  "name": "Football",
195
216
  "decimal": "14.99",
196
- "in-stock": false
217
+ "in_stock": false
197
218
  }
198
219
  ],
199
220
  "customer": {
@@ -226,7 +247,7 @@ data = OrderDeSer.serialize([order, order2])
226
247
 
227
248
  ### Object Deserialization
228
249
 
229
- **Note:** Objects that are parsed must have a zero-argument initializer (ie: Object.new)
250
+ **Note:** Objects that are parsed must have a zero argument initializer (ie: Object.new)
230
251
 
231
252
  #### Parsing a hash
232
253
 
@@ -504,21 +525,30 @@ class UserDeSer < De::Ser::Ializer
504
525
  end
505
526
  ```
506
527
 
507
- **Note:** Because of scoping, including a deser using `with` will not include any method overrides
528
+ **Note:** Including a deser using `with` will include any method overrides.
508
529
 
509
530
  ```ruby
510
531
  class BaseApiDeSer < De::Ser::Ializer
511
532
  integer :id
512
533
  timestamp :created_at
534
+ timestamp :updated_at
513
535
 
514
536
  def self.created_at(object, context)
515
- # NOT INCLUDED IN UserDeSer. UserDeSer will call `.created_at` on any serialization target
537
+ # INCLUDED IN UserDeSer
538
+ end
539
+
540
+ def self.updated_at(object, context)
541
+ # NOT INCLUDED IN UserDeSer(Overridden below)
516
542
  end
517
543
  end
518
544
 
519
545
  class UserDeSer < De::Ser::Ializer
520
546
  with BaseApiDeSer
521
547
  string :email
548
+
549
+ def self.updated_at(object, context)
550
+ # INCLUDED IN UserDeSer.
551
+ end
522
552
  end
523
553
  ```
524
554
 
@@ -53,6 +53,8 @@ module De
53
53
  private
54
54
 
55
55
  def parse_field(object, field, value)
56
+ return if value.nil?
57
+
56
58
  parsed_value = field.parse(value)
57
59
 
58
60
  return if parsed_value.nil?
@@ -5,10 +5,14 @@ require 'bigdecimal'
5
5
  module Ializer
6
6
  class BigDecimalDeSer
7
7
  def self.serialize(value, _context = nil)
8
+ value = value.to_d unless value.is_a? BigDecimal
9
+
8
10
  value.to_s('F')
9
11
  end
10
12
 
11
13
  def self.parse(value)
14
+ return nil if value.nil?
15
+
12
16
  BigDecimal(value)
13
17
  end
14
18
  end
@@ -10,7 +10,7 @@ module Ializer
10
10
  # :key_transform=: key_transform
11
11
  #
12
12
  # symbol of string transform to call on field keys
13
- # default is +:dasherize+.
13
+ # default is nil
14
14
  def key_transform=(key_transform)
15
15
  self.key_transformer = key_transform&.to_proc
16
16
  end
@@ -10,7 +10,7 @@ module Ializer
10
10
 
11
11
  def self.parse(value)
12
12
  Date.parse(value)
13
- rescue ArgumentError
13
+ rescue ArgumentError, TypeError
14
14
  nil
15
15
  end
16
16
  end
@@ -9,6 +9,8 @@ module Ializer
9
9
  end
10
10
 
11
11
  def self.parse(value)
12
+ return nil if value.nil?
13
+
12
14
  Time.at(value / 1000.0)
13
15
  end
14
16
  end
@@ -7,6 +7,8 @@ module Ializer
7
7
  end
8
8
 
9
9
  def self.parse(value)
10
+ return nil if value.nil?
11
+
10
12
  value.to_sym
11
13
  end
12
14
  end
@@ -10,6 +10,8 @@ module Ializer
10
10
 
11
11
  def self.parse(value)
12
12
  DateTime.iso8601 value
13
+ rescue ArgumentError
14
+ nil
13
15
  end
14
16
  end
15
17
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ializer
4
- VERSION = '0.2.0'
4
+ VERSION = '0.7.0'
5
5
  end
@@ -5,9 +5,24 @@ module Ser
5
5
  @@method_registry = {} # rubocop:disable Style/ClassVars
6
6
 
7
7
  class << self
8
+ def config
9
+ @config ||=
10
+ if equal? Ser::Ializer
11
+ ::Ializer.config
12
+ else
13
+ superclass.config
14
+ end
15
+ end
16
+
17
+ def setup
18
+ @config = config.dup
19
+
20
+ yield @config
21
+ end
22
+
8
23
  # Public DSL
9
24
  def property(name, options = {}, &block)
10
- return add_attribute(Field.new(name, options, &block)) if options[:deser]
25
+ return add_attribute(Field.new(name, options, config, &block)) if options[:deser]
11
26
 
12
27
  return default(name, options, &block) unless options[:type]
13
28
 
@@ -25,17 +40,21 @@ module Ser
25
40
  options[:deser] = deser
26
41
  end
27
42
 
28
- add_attribute(Field.new(name, options))
43
+ add_attribute(Field.new(name, options, config))
29
44
  end
30
45
 
31
46
  def with(deser)
32
- deser._attributes.values.map(&:dup).each(&method(:add_attribute))
47
+ deser._attributes.values.each do |field|
48
+ add_composed_attribute(field, deser)
49
+ end
33
50
  end
34
51
  # End Public DSL
35
52
 
36
53
  def serialize(object, context = nil)
37
54
  return serialize_one(object, context) unless valid_enumerable?(object)
38
55
 
56
+ return [] if object.empty?
57
+
39
58
  object.map { |o| serialize_one(o, context) }
40
59
  end
41
60
 
@@ -48,7 +67,7 @@ module Ser
48
67
 
49
68
  define_singleton_method(method_name) do |name, options = {}, &block|
50
69
  options[:deser] = deser
51
- add_attribute Field.new(name, options, &block)
70
+ add_attribute Field.new(name, options, config, &block)
52
71
  end
53
72
 
54
73
  matchers.each do |matcher|
@@ -58,12 +77,12 @@ module Ser
58
77
 
59
78
  def register_default(deser)
60
79
  define_singleton_method('default') do |name, options = {}, &block|
61
- raise ArgumentError, warning_message(name) if ::Ializer.config.raise_on_default?
80
+ raise ArgumentError, warning_message(name) if config.raise_on_default?
62
81
 
63
- puts warning_message(name) if ::Ializer.config.warn_on_default?
82
+ puts warning_message(name) if config.warn_on_default?
64
83
 
65
84
  options[:deser] = deser
66
- add_attribute Field.new(name, options, &block)
85
+ add_attribute Field.new(name, options, config, &block)
67
86
  end
68
87
  end
69
88
 
@@ -107,26 +126,18 @@ module Ser
107
126
  def add_attribute(field)
108
127
  _attributes[field.key] = field
109
128
 
110
- if field.block
111
- add_attribute_with_block(field)
112
- else
113
- add_attribute_with_method(field)
114
- end
115
- end
116
-
117
- def add_attribute_with_block(field)
118
129
  define_singleton_method field.name do |object, context|
119
- value = field.block.call(object, context)
130
+ value = field.get_value(object, context)
120
131
 
121
132
  serialize_field(field, value, context)
122
133
  end
123
134
  end
124
135
 
125
- def add_attribute_with_method(field)
126
- define_singleton_method field.name do |object, context|
127
- value = object.public_send(field.name)
136
+ def add_composed_attribute(field, deser)
137
+ _attributes[field.key] = field
128
138
 
129
- serialize_field(field, value, context)
139
+ define_singleton_method field.name do |object, context|
140
+ deser.public_send(field.name, object, context)
130
141
  end
131
142
  end
132
143
 
@@ -135,6 +146,8 @@ module Ser
135
146
 
136
147
  return field.serialize(value, context) unless valid_enumerable?(value)
137
148
 
149
+ return nil if value.empty?
150
+
138
151
  value.map { |v| field.serialize(v, context) }
139
152
  end
140
153
 
@@ -4,25 +4,31 @@ module Ser
4
4
  class Ializer
5
5
  class Field
6
6
  class << self
7
- def transform(key)
8
- return key unless ::Ializer.config.key_transformer
7
+ def transform(key, key_transformer)
8
+ return key unless key_transformer
9
9
 
10
- ::Ializer.config.key_transformer.call(key)
10
+ key_transformer.call(key)
11
11
  end
12
12
  end
13
13
 
14
14
  attr_reader :name, :setter, :key, :deser, :model_class, :if_condition, :block
15
15
 
16
- def initialize(name, options, &block)
16
+ def initialize(name, options, config, &block)
17
17
  @name = name
18
18
  @setter = options[:setter] || "#{name}="
19
- @key = options[:key] || Field.transform(name.to_s)
19
+ @key = options[:key] || Field.transform(name.to_s, config.key_transformer)
20
20
  @deser = options[:deser]
21
21
  @if_condition = options[:if]
22
22
  @model_class = options[:model_class]
23
23
  @block = block
24
24
  end
25
25
 
26
+ def get_value(object, context)
27
+ return object.public_send(name) unless block
28
+
29
+ block.call(object, context)
30
+ end
31
+
26
32
  def serialize(value, context)
27
33
  deser.serialize(value, context)
28
34
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ializer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Steinberg
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-01-07 00:00:00.000000000 Z
11
+ date: 2020-06-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport