glue_gun_dsl 0.1.29 → 0.1.30

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: 1c7ef75df045c142a9b1175b91ad7f7745179ea3dacfa5c30c2b2409e1d4fe78
4
- data.tar.gz: 3e55b0b662c7ccf655e784cc9672a5e6f7a792268bd0140d28e66b8b4439b627
3
+ metadata.gz: 43d8acb6f057ab8a1af500f7c179ab11799e76a5a00936e3b75c2e8d89ebf31b
4
+ data.tar.gz: c1eca08d776bb20638e544ccf4263a65cabde137bbc821f871b0f0898b7b062d
5
5
  SHA512:
6
- metadata.gz: f97de5312eaaae95f2c57bd8691a4751f55902ffdd7f8140d0f11a6548c2004afc47f31612f1e7ad14b42e2d530bdbf588349a9e8c4c0645a8dc760da3b383c4
7
- data.tar.gz: 11916bd9c893ce87058a1fbf1e4f2b4b9fbcd16b8867493e35c932622e8ebcbe43ed8cee3291219aa24a274cb60a79f6d1f9ae15c67c712e1bf3f3398805f6a6
6
+ metadata.gz: 5560e86452000ea065de2721466104a8c1f108db0b57c608c8248ab84565e317db518ea93be0ea2bad3f148075ac78666fed7c48674f59978af07196d485a8b6
7
+ data.tar.gz: 0b384297f71a53a34f3def7fe0542ed993e5fb9c09160f0ec4f10b39a4481a83503d7e5b38337f4eea597eba6c3f73adecce59d551886b6d1bfc6d137e61452d
@@ -1,4 +1,5 @@
1
1
  require_relative "shared"
2
+ require_relative "serializers"
2
3
  module GlueGun
3
4
  module Model
4
5
  extend ActiveSupport::Concern
@@ -217,119 +218,20 @@ module GlueGun
217
218
  end.symbolize_keys
218
219
  end
219
220
 
220
- def serialize_object(object)
221
- if object.respond_to?(:serialize)
222
- object.serialize
223
- elsif object.respond_to?(:attributes)
224
- object.attributes.deep_compact
225
- else
226
- Hash[object.instance_variables.map do |var|
227
- [var.to_s.delete("@"), object.instance_variable_get(var)]
228
- end].deep_compact
229
- end
230
- end
231
-
232
- def serialize_dependency(dependency, dep_instance = nil)
233
- dep_instance = service_object.send(dependency) if dep_instance.nil?
234
- return nil unless dep_instance.present?
235
-
236
- return dep_instance.map { |dep| serialize_dependency(dependency, dep) } if dep_instance.is_a?(Array)
237
-
238
- opts = service_object.dependency_definitions[dependency].option_configs
239
- selected_option = opts.detect do |_k, v|
240
- dep_instance.class == v.class_name
241
- end&.first
242
- unless selected_option.present?
243
- raise "Don't know how to serialize dependency of type #{dependency}, available options are #{opts.keys}. You didn't specify an option."
244
- end
245
-
246
- serialized = serialize_object(dep_instance)
247
- {
248
- selected_option => serialized
249
- }
250
- end
251
-
252
221
  def service_object
253
222
  instance_variable_get("@#{service_attribute_name}")
254
223
  end
255
224
 
256
- def service_class
257
- service_object.class
258
- end
259
-
260
225
  def serialize_service_object
261
- attrs = serialize_object(service_object)
262
- deps = allowed_names(service_object.dependency_definitions.keys).inject({}) do |hash, dep|
263
- hash.tap do
264
- serialized = serialize_dependency(dep)
265
- next if serialized.nil?
266
-
267
- hash[dep] = serialized
268
- end
269
- end
270
- json = serializable!(attrs.merge(deps).deep_symbolize_keys)
271
- write_attribute(:configuration, json.to_json)
272
- end
273
-
274
- def serializable!(json)
275
- regular_args = json.slice(*allowed_names(json.keys))
276
- assoc_names = self.class.reflect_on_all_associations.map(&:name)
277
- found_associations = assoc_names & json.keys
278
- found_associations.each do |association|
279
- regular_args[association] = true
280
- end
281
- regular_args
282
- end
283
-
284
- def deserialize_associations(json)
285
- assoc_names = self.class.reflect_on_all_associations.map(&:name)
286
- found_associations = assoc_names & json.keys
287
- found_associations.each do |association|
288
- json[association] = send(association)
289
- end
290
- json
291
- end
292
-
293
- def deserialize_dependency(serialized, definition)
294
- return serialized.map { |dep| deserialize_dependency(dep, definition) } if serialized.is_a?(Array)
295
-
296
- dep_name = serialized.keys.first
297
- selected_option = definition.option_configs[dep_name]
298
- dependency_class = selected_option.class_name
299
- arguments = serialized[dep_name]
300
-
301
- dependency_class.respond_to?(:deserialize) ? dependency_class.deserialize(arguments) : arguments
302
- {
303
- dep_name => arguments
304
- }
305
- end
306
-
307
- def deserialize_dependencies(serialized_data, service_class)
308
- serialized_deps = (serialized_data.keys & allowed_names(service_class.dependency_definitions.keys))
309
- serialized_deps.each do |name|
310
- serialized = serialized_data[name]
311
- definition = service_class.dependency_definitions[name]
312
- serialized_data[name] = deserialize_dependency(serialized, definition)
313
- end
314
- serialized_data
226
+ GlueGun::Serializers.new(self).serialize_service_object(service_object)
315
227
  end
316
228
 
317
229
  def deserialize_service_object
318
- serialized_data = JSON.parse(read_attribute(:configuration) || "{}")
319
- serialized_data.deep_symbolize_keys!
320
- service_class = resolve_service_class(serialized_data)
321
- serialized_data = deserialize_associations(serialized_data)
322
- serialized_data = service_class.deserialize(serialized_data) if service_class.respond_to?(:deserialize)
323
- serialized_data = deserialize_dependencies(serialized_data, service_class)
324
- service_instance = build_service_object(serialized_data)
230
+ deserialized = GlueGun::Serializers.new(self).deserialize_service_object
231
+ service_instance = build_service_object(deserialized)
325
232
  instance_variable_set("@#{service_attribute_name}", service_instance)
326
233
  end
327
234
 
328
- def allowed_names(names)
329
- assoc_names = self.class.reflect_on_all_associations.map(&:name)
330
- [names.map(&:to_sym) - assoc_names.map(&:to_sym)].flatten
331
- end
332
-
333
235
  def method_missing(method_name, *args, **kwargs, &block)
334
236
  service_object = instance_variable_get("@#{service_attribute_name}")
335
237
 
@@ -0,0 +1,164 @@
1
+ module GlueGun
2
+ class Serializers
3
+ attr_accessor :instance
4
+
5
+ def initialize(instance)
6
+ @instance = instance
7
+ end
8
+
9
+ def serialize_object(object)
10
+ if object.respond_to?(:serialize)
11
+ object.serialize
12
+ elsif object.respond_to?(:attributes)
13
+ object.attributes.deep_compact
14
+ else
15
+ Hash[object.instance_variables.map do |var|
16
+ [var.to_s.delete("@"), object.instance_variable_get(var)]
17
+ end].deep_compact
18
+ end
19
+ end
20
+
21
+ def serialize_dependency(service_object, dependency, dep_instance = nil)
22
+ dep_instance = service_object.send(dependency) if dep_instance.nil?
23
+ return nil unless dep_instance.present?
24
+
25
+ if dep_instance.is_a?(Array)
26
+ return dep_instance.map do |dep|
27
+ serialize_dependency(service_object, dependency, dep)
28
+ end
29
+ end
30
+
31
+ opts = service_object.dependency_definitions[dependency].option_configs
32
+ selected_option = opts.detect do |_k, v|
33
+ dep_instance.class == v.class_name
34
+ end&.first
35
+ unless selected_option.present?
36
+ raise "Don't know how to serialize dependency of type #{dependency}, available options are #{opts.keys}. You didn't specify an option."
37
+ end
38
+
39
+ serialized = serialize_object(dep_instance)
40
+ {
41
+ selected_option => serialized
42
+ }
43
+ end
44
+
45
+ def service_class
46
+ service_object.class
47
+ end
48
+
49
+ def allowed_names(names)
50
+ assoc_names = instance.class.reflect_on_all_associations.map(&:name)
51
+ [names.map(&:to_sym) - assoc_names.map(&:to_sym)].flatten
52
+ end
53
+
54
+ def serialize_service_object(service_object)
55
+ attrs = serialize_object(service_object)
56
+ deps = allowed_names(service_object.dependency_definitions.keys).inject({}) do |hash, dep|
57
+ hash.tap do
58
+ serialized = serialize_dependency(service_object, dep)
59
+ next if serialized.nil?
60
+
61
+ hash[dep] = serialized
62
+ end
63
+ end
64
+ json = serializable!(serialize_attrs(attrs.merge(deps).deep_symbolize_keys))
65
+ instance.write_attribute(:configuration, json.to_json)
66
+ end
67
+
68
+ def serializable!(json)
69
+ regular_args = json.slice(*allowed_names(json.keys))
70
+ assoc_names = instance.class.reflect_on_all_associations.map(&:name)
71
+ found_associations = assoc_names & json.keys
72
+ found_associations.each do |association|
73
+ regular_args[association] = true
74
+ end
75
+ regular_args
76
+ end
77
+
78
+ def deserialize_associations(json)
79
+ assoc_names = instance.class.reflect_on_all_associations.map(&:name)
80
+ found_associations = assoc_names & json.keys
81
+ found_associations.each do |association|
82
+ json[association] = instance.send(association)
83
+ end
84
+ json
85
+ end
86
+
87
+ def deserialize_dependency(serialized, definition)
88
+ return serialized.map { |dep| deserialize_dependency(dep, definition) } if serialized.is_a?(Array)
89
+
90
+ dep_name = serialized.keys.first
91
+ selected_option = definition.option_configs[dep_name]
92
+ dependency_class = selected_option.class_name
93
+ arguments = serialized[dep_name]
94
+
95
+ dependency_class.respond_to?(:deserialize) ? dependency_class.deserialize(arguments) : arguments
96
+ {
97
+ dep_name => arguments
98
+ }
99
+ end
100
+
101
+ def deserialize_dependencies(serialized_data, service_class)
102
+ serialized_deps = (serialized_data.keys & allowed_names(service_class.dependency_definitions.keys))
103
+ serialized_deps.each do |name|
104
+ serialized = serialized_data[name]
105
+ definition = service_class.dependency_definitions[name]
106
+ serialized_data[name] = deserialize_dependency(serialized, definition)
107
+ end
108
+ serialized_data
109
+ end
110
+
111
+ def deserialize_service_object
112
+ serialized_data = JSON.parse(instance.read_attribute(:configuration) || "{}")
113
+ serialized_data.deep_symbolize_keys!
114
+ serialized_data = deserialize_attrs(serialized_data)
115
+ service_class = instance.send(:resolve_service_class, serialized_data)
116
+ serialized_data = deserialize_associations(serialized_data)
117
+ serialized_data = service_class.deserialize(serialized_data) if service_class.respond_to?(:deserialize)
118
+ deserialize_dependencies(serialized_data, service_class)
119
+ end
120
+
121
+ def serialize_attrs(attrs)
122
+ attrs.deep_transform_values do |value|
123
+ case value
124
+ when ActiveSupport::TimeWithZone
125
+ { "__type__" => "ActiveSupport::TimeWithZone", "value" => value.iso8601 }
126
+ else
127
+ value
128
+ end
129
+ end
130
+ end
131
+
132
+ def deserialize_attrs(attrs)
133
+ return nil if attrs.nil?
134
+
135
+ attrs.transform_values do |value|
136
+ recursive_deserialize(value)
137
+ end
138
+ end
139
+
140
+ def recursive_deserialize(value)
141
+ case value
142
+ when Hash
143
+ if value[:__type__]
144
+ deserialize_special_type(value)
145
+ else
146
+ value.transform_values { |v| recursive_deserialize(v) }
147
+ end
148
+ when Array
149
+ value.map { |v| recursive_deserialize(v) }
150
+ else
151
+ value
152
+ end
153
+ end
154
+
155
+ def deserialize_special_type(value)
156
+ case value[:__type__]
157
+ when "ActiveSupport::TimeWithZone"
158
+ Time.zone.parse(value[:value])
159
+ else
160
+ value[:value]
161
+ end
162
+ end
163
+ end
164
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GlueGun
4
- VERSION = "0.1.29"
4
+ VERSION = "0.1.30"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glue_gun_dsl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.29
4
+ version: 0.1.30
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brett Shollenberger
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-10-25 00:00:00.000000000 Z
11
+ date: 2024-10-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -196,6 +196,20 @@ dependencies:
196
196
  - - "~>"
197
197
  - !ruby/object:Gem::Version
198
198
  version: '1.4'
199
+ - !ruby/object:Gem::Dependency
200
+ name: timecop
201
+ requirement: !ruby/object:Gem::Requirement
202
+ requirements:
203
+ - - ">="
204
+ - !ruby/object:Gem::Version
205
+ version: '0'
206
+ type: :development
207
+ prerelease: false
208
+ version_requirements: !ruby/object:Gem::Requirement
209
+ requirements:
210
+ - - ">="
211
+ - !ruby/object:Gem::Version
212
+ version: '0'
199
213
  description: GlueGun makes dependency injection and hydration a first-order concern
200
214
  email:
201
215
  - brett.shollenberger@gmail.com
@@ -208,6 +222,7 @@ files:
208
222
  - lib/glue_gun/core_ext/hash_extensions.rb
209
223
  - lib/glue_gun/dsl.rb
210
224
  - lib/glue_gun/model.rb
225
+ - lib/glue_gun/serializers.rb
211
226
  - lib/glue_gun/shared.rb
212
227
  - lib/glue_gun/types.rb
213
228
  - lib/glue_gun/types/array_type.rb