ializer 0.6.0 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 65d2290293ec3f08da6cf2b4b4ce3f30c7240ace2157380f6394c578902f6057
4
- data.tar.gz: b7c0e5883f3133c4ea215648af2133cdb8d00153dbd1b53c2a08f3518c62bac7
3
+ metadata.gz: 436adbeed83a5f03cb2f5efe5f1ed07f3e7647e7fa15732e7af92923bc6165f5
4
+ data.tar.gz: c4d2dbc6a03164d51eb577a6a1fe084f35dca996739b75c6d78d7760dfb434cc
5
5
  SHA512:
6
- metadata.gz: 14e4e920d24d0a3857dea918cbb318030887c4d5c2ee2c8c27bff61d547fb8c86cc54b573ff142d13c32daf78fbf9efc289d4204d16615cbcee1fbf1b583b5b5
7
- data.tar.gz: bfa543caebda04f6bb6ccec07c93bda3b8e57e2f94a63b3221ffa04294467fb88ff9cdbb72ade621450554ff44f103efb932734f81aaa66cc7018cc8b16799d1
6
+ metadata.gz: b563551fb9ebdb39f866c6c1fe58977b9e5c074d1ba4bf0e5a3d040efe191056f4728549e0e36cc34b6f33801aecd83638885c86f04affb07c2c28726ca2f38e
7
+ data.tar.gz: 82aa9bb2072c937b1f23464418744eb7fff88cb90ea8d97b2ce5f9e99249aa71e59f6050b5da6d014bb9edc5d62c6561b127ac14204502ead6b5cfecd3a1dd89
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
 
@@ -271,7 +292,7 @@ class OrderDeSer < De::Ser::Ializer
271
292
 
272
293
  nested :items, deser: OrderItemDeSer, model_class: OrderItem
273
294
  # OR
274
- property :items, deser: OrderItemDeSer, model_classx: OrderItem
295
+ property :items, deser: OrderItemDeSer, model_class: OrderItem
275
296
 
276
297
  nested :customer, model_class: Customer do
277
298
  string :name
@@ -437,6 +458,27 @@ end
437
458
  CustomerDeSer.serialize(order, current_user)
438
459
  ```
439
460
 
461
+ #### Using the context to serialize a subset of attributes
462
+
463
+ There are special keywords/method names on the Serialization Context that can be used to limit the attributes that are serialized. This is different from conditional attributes below. The conditions would still apply to the subset.
464
+
465
+ If your serialization context is a `Hash`, you can use the hash keys `:attributes` or `:include` to define the limited subset of attributes for serialization.
466
+
467
+ ```ruby
468
+ CustomerDeSer.serialize(order, attributes: [:name])
469
+ ```
470
+
471
+ If your serialization context is a ruby object, a method named `attributes` that returns an array of attribute names can be used.
472
+
473
+ ```ruby
474
+ class AttributeSubsetContext
475
+ attr_accessor :attributes
476
+ end
477
+
478
+ context = AttributeSubsetContext.new(attributes: [:name])
479
+ CustomerDeSer.serialize(order, context)
480
+ ```
481
+
440
482
  ### Conditional Attributes
441
483
 
442
484
  Conditional attributes can be defined by passing a Proc to the `if` key on the `property` method. Return `truthy` if the attribute should be serialized, and `falsey` if not. The record and any params passed to the serializer are available inside the Proc as the first and second parameters, respectively.
data/ializer.gemspec CHANGED
@@ -28,7 +28,7 @@ Gem::Specification.new do |spec|
28
28
  spec.add_development_dependency 'pry'
29
29
  spec.add_development_dependency 'rake'
30
30
  spec.add_development_dependency 'rspec'
31
- spec.add_development_dependency 'rubocop'
31
+ spec.add_development_dependency 'rubocop', '~> 0.78.0'
32
32
  spec.add_development_dependency 'rubocop-rspec'
33
33
  spec.add_development_dependency 'simplecov'
34
34
  end
@@ -14,6 +14,8 @@ module Ializer
14
14
  return nil if value.nil?
15
15
 
16
16
  BigDecimal(value)
17
+ rescue ArgumentError
18
+ value
17
19
  end
18
20
  end
19
21
  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
@@ -11,7 +11,7 @@ module Ializer
11
11
  def self.parse(value)
12
12
  Date.parse(value)
13
13
  rescue ArgumentError, TypeError
14
- nil
14
+ value
15
15
  end
16
16
  end
17
17
  end
@@ -9,6 +9,8 @@ module Ializer
9
9
  def self.parse(value)
10
10
  return value if value.is_a? Numeric
11
11
 
12
+ return nil if value.nil?
13
+
12
14
  value.to_i
13
15
  end
14
16
  end
@@ -23,6 +23,8 @@ module Ializer
23
23
 
24
24
  return Float::INFINITY if value == INFINITY_STRING
25
25
 
26
+ return nil if value.nil?
27
+
26
28
  value.to_f
27
29
  end
28
30
  end
@@ -12,6 +12,8 @@ module Ializer
12
12
  return nil if value.nil?
13
13
 
14
14
  Time.at(value / 1000.0)
15
+ rescue NoMethodError
16
+ value
15
17
  end
16
18
  end
17
19
  end
@@ -10,6 +10,8 @@ module Ializer
10
10
  return nil if value.nil?
11
11
 
12
12
  value.to_sym
13
+ rescue NoMethodError
14
+ value
13
15
  end
14
16
  end
15
17
  end
@@ -11,7 +11,7 @@ module Ializer
11
11
  def self.parse(value)
12
12
  DateTime.iso8601 value
13
13
  rescue ArgumentError
14
- nil
14
+ value
15
15
  end
16
16
  end
17
17
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ializer
4
- VERSION = '0.6.0'
4
+ VERSION = '0.9.1'
5
5
  end
data/lib/ser/ializer.rb CHANGED
@@ -1,13 +1,31 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'active_support/hash_with_indifferent_access'
4
+ require 'active_support/core_ext/hash'
5
+
3
6
  module Ser
4
7
  class Ializer # rubocop:disable Metrics/ClassLength
5
8
  @@method_registry = {} # rubocop:disable Style/ClassVars
6
9
 
7
10
  class << self
11
+ def config
12
+ @config ||=
13
+ if equal? Ser::Ializer
14
+ ::Ializer.config
15
+ else
16
+ superclass.config
17
+ end
18
+ end
19
+
20
+ def setup
21
+ @config = config.dup
22
+
23
+ yield @config
24
+ end
25
+
8
26
  # Public DSL
9
27
  def property(name, options = {}, &block)
10
- return add_attribute(Field.new(name, options, &block)) if options[:deser]
28
+ return add_attribute(Field.new(name, options, config, &block)) if options[:deser]
11
29
 
12
30
  return default(name, options, &block) unless options[:type]
13
31
 
@@ -25,7 +43,7 @@ module Ser
25
43
  options[:deser] = deser
26
44
  end
27
45
 
28
- add_attribute(Field.new(name, options))
46
+ add_attribute(Field.new(name, options, config))
29
47
  end
30
48
 
31
49
  def with(deser)
@@ -52,7 +70,7 @@ module Ser
52
70
 
53
71
  define_singleton_method(method_name) do |name, options = {}, &block|
54
72
  options[:deser] = deser
55
- add_attribute Field.new(name, options, &block)
73
+ add_attribute Field.new(name, options, config, &block)
56
74
  end
57
75
 
58
76
  matchers.each do |matcher|
@@ -62,12 +80,12 @@ module Ser
62
80
 
63
81
  def register_default(deser)
64
82
  define_singleton_method('default') do |name, options = {}, &block|
65
- raise ArgumentError, warning_message(name) if ::Ializer.config.raise_on_default?
83
+ raise ArgumentError, warning_message(name) if config.raise_on_default?
66
84
 
67
- puts warning_message(name) if ::Ializer.config.warn_on_default?
85
+ puts warning_message(name) if config.warn_on_default?
68
86
 
69
87
  options[:deser] = deser
70
- add_attribute Field.new(name, options, &block)
88
+ add_attribute Field.new(name, options, config, &block)
71
89
  end
72
90
  end
73
91
 
@@ -96,7 +114,7 @@ module Ser
96
114
  def _attributes
97
115
  @attributes ||=
98
116
  if equal? Ser::Ializer
99
- {}
117
+ ActiveSupport::HashWithIndifferentAccess.new
100
118
  else
101
119
  superclass._attributes.dup
102
120
  end
@@ -137,7 +155,7 @@ module Ser
137
155
  end
138
156
 
139
157
  def serialize_one(object, context)
140
- _attributes.values.each_with_object({}) do |field, data|
158
+ fields_for_serialization(context).each_with_object({}) do |field, data|
141
159
  next unless field.valid_for_context?(object, context)
142
160
 
143
161
  value = public_send(field.name, object, context)
@@ -148,6 +166,27 @@ module Ser
148
166
  end
149
167
  end
150
168
 
169
+ def fields_for_serialization(context)
170
+ field_names = fields_names_for_serialization(context)
171
+
172
+ return _attributes.values unless field_names
173
+
174
+ _attributes.values_at(*field_names).compact
175
+ end
176
+
177
+ def fields_names_for_serialization(context)
178
+ return nil unless context
179
+
180
+ if context.is_a?(Hash)
181
+ context = context.with_indifferent_access
182
+ return context[:attributes] || context[:include]
183
+ end
184
+
185
+ return context.attributes if context.respond_to?(:attributes)
186
+
187
+ nil
188
+ end
189
+
151
190
  def valid_enumerable?(object)
152
191
  return true if object.is_a? Array
153
192
 
@@ -4,19 +4,19 @@ 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]
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.6.0
4
+ version: 0.9.1
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-06-01 00:00:00.000000000 Z
11
+ date: 2021-07-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -98,16 +98,16 @@ dependencies:
98
98
  name: rubocop
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - ">="
101
+ - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: '0'
103
+ version: 0.78.0
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - ">="
108
+ - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: '0'
110
+ version: 0.78.0
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: rubocop-rspec
113
113
  requirement: !ruby/object:Gem::Requirement