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 +4 -4
- data/lib/glue_gun/model.rb +4 -102
- data/lib/glue_gun/serializers.rb +164 -0
- data/lib/glue_gun/version.rb +1 -1
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 43d8acb6f057ab8a1af500f7c179ab11799e76a5a00936e3b75c2e8d89ebf31b
|
4
|
+
data.tar.gz: c1eca08d776bb20638e544ccf4263a65cabde137bbc821f871b0f0898b7b062d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5560e86452000ea065de2721466104a8c1f108db0b57c608c8248ab84565e317db518ea93be0ea2bad3f148075ac78666fed7c48674f59978af07196d485a8b6
|
7
|
+
data.tar.gz: 0b384297f71a53a34f3def7fe0542ed993e5fb9c09160f0ec4f10b39a4481a83503d7e5b38337f4eea597eba6c3f73adecce59d551886b6d1bfc6d137e61452d
|
data/lib/glue_gun/model.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
319
|
-
|
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
|
data/lib/glue_gun/version.rb
CHANGED
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.
|
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-
|
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
|