simply_serializable 1.2.2 → 1.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 +4 -4
- data/Gemfile.lock +1 -1
- data/lib/simply_serializable/mixin.rb +6 -8
- data/lib/simply_serializable/serializer.rb +107 -39
- data/lib/simply_serializable/version.rb +1 -1
- data/lib/simply_serializable.rb +19 -1
- metadata +2 -3
- data/.byebug_history +0 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ed7754c68910d4556534b53f8475b8c36d1ad9259408508523c3bbd5463d0157
|
4
|
+
data.tar.gz: 39eb74d95beb65aee78582fba369bbe5bd76ef082ad9d5a5cedf28f5d738ceb3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 90156f91281bb1fdf486351962b3380ee430866feea4418f2644d72e07d4f60c3346459b7125e81e3141bdcd488e626be0aa4f9572782a9eb1b3dbd6d6f09f03
|
7
|
+
data.tar.gz: 455a807775db2e60c18f670e2c8ed080cd8995d3164c356e33897919c3af71315c26d21cdd038831f07246ca1c22acb1fe3873db1803d72f69420665392c0ab9
|
data/Gemfile.lock
CHANGED
@@ -35,13 +35,15 @@ module SimplySerializable
|
|
35
35
|
base.extend(ClassMethods)
|
36
36
|
end
|
37
37
|
|
38
|
-
def serialize(cache: {})
|
39
|
-
serializer(cache: cache).serialize
|
38
|
+
def serialize(cache: {}, **options)
|
39
|
+
serializer(cache: cache, **options).serialize
|
40
40
|
end
|
41
41
|
|
42
|
-
def serializer(cache: {})
|
42
|
+
def serializer(cache: {}, **options)
|
43
43
|
Serializer.new(
|
44
44
|
**self.class.serializable_config.merge(
|
45
|
+
options
|
46
|
+
).merge(
|
45
47
|
cache: cache,
|
46
48
|
object: self
|
47
49
|
)
|
@@ -49,11 +51,7 @@ module SimplySerializable
|
|
49
51
|
end
|
50
52
|
|
51
53
|
def serializable_id
|
52
|
-
|
53
|
-
end
|
54
|
-
|
55
|
-
def serializable_type
|
56
|
-
self.class.name
|
54
|
+
serializer.id
|
57
55
|
end
|
58
56
|
end
|
59
57
|
end
|
@@ -17,47 +17,57 @@ module SimplySerializable
|
|
17
17
|
only: nil
|
18
18
|
)
|
19
19
|
@object = object
|
20
|
+
@id = id
|
20
21
|
@attributes = attributes
|
21
22
|
@include_readable_instance_variables = include_readable_instance_variables
|
22
23
|
@except = except&.map(&:to_sym)
|
23
24
|
@only = only&.map(&:to_sym)
|
24
25
|
@method_prefix = method_prefix
|
25
|
-
@
|
26
|
-
@
|
27
|
-
@serialized = false
|
26
|
+
@local_cache = cache
|
27
|
+
@local_cache[cache_key] = nil
|
28
28
|
|
29
29
|
populate_attributes
|
30
30
|
end
|
31
31
|
|
32
32
|
def cache
|
33
|
-
|
34
|
-
|
33
|
+
@cache ||= begin
|
34
|
+
serialize
|
35
|
+
@local_cache
|
36
|
+
end
|
35
37
|
end
|
36
38
|
|
37
|
-
def
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
39
|
+
def id
|
40
|
+
@id ||= cache_key
|
41
|
+
end
|
42
|
+
|
43
|
+
def nestable?
|
44
|
+
return @nestable unless @nestable.nil?
|
45
|
+
|
46
|
+
serialize
|
47
|
+
@nestable
|
48
|
+
end
|
49
|
+
|
50
|
+
def nested
|
51
|
+
@nested ||= begin
|
52
|
+
deep_nest(serialize[:root])
|
49
53
|
end
|
50
54
|
end
|
51
55
|
|
52
56
|
def serialize
|
53
57
|
@serialize ||= begin
|
54
|
-
@
|
58
|
+
@nestable = true
|
55
59
|
ret = deep_serialize(object_value_hash)
|
56
60
|
|
57
|
-
|
61
|
+
@local_cache[cache_key] = {
|
62
|
+
id: cache_key,
|
63
|
+
object: object.class.name,
|
64
|
+
fingeprint: fingerprint,
|
65
|
+
data: ret
|
66
|
+
}
|
67
|
+
|
58
68
|
{
|
59
69
|
root: cache_key,
|
60
|
-
objects:
|
70
|
+
objects: @local_cache
|
61
71
|
}
|
62
72
|
end
|
63
73
|
end
|
@@ -68,6 +78,50 @@ module SimplySerializable
|
|
68
78
|
|
69
79
|
private
|
70
80
|
|
81
|
+
def cache_key
|
82
|
+
@cache_key ||= cache_key_for(object)
|
83
|
+
end
|
84
|
+
|
85
|
+
def cache_key_for(obj)
|
86
|
+
"#{obj.class.name}/#{fingerprint_for(obj)}"
|
87
|
+
end
|
88
|
+
|
89
|
+
def deep_nest(obj_id)
|
90
|
+
raise Error::CircularDependencyError unless @nestable
|
91
|
+
|
92
|
+
Hash[@local_cache[obj_id][:data].map do |k, v|
|
93
|
+
v = deep_nest(v.dig(:id)) if v.is_a?(Hash) && v.dig(:object) == :reference
|
94
|
+
[k, v]
|
95
|
+
end]
|
96
|
+
end
|
97
|
+
|
98
|
+
def deep_serialize(obj)
|
99
|
+
case obj
|
100
|
+
when FalseClass, Float, nil, Integer, String, Symbol, TrueClass
|
101
|
+
obj
|
102
|
+
when Array
|
103
|
+
obj.map { |v| deep_serialize(v) }
|
104
|
+
when Hash
|
105
|
+
Hash[obj.map { |k, v| [deep_serialize(k), deep_serialize(v)] }]
|
106
|
+
when Module
|
107
|
+
obj.name
|
108
|
+
else
|
109
|
+
serialize_object(obj)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def fingerprint
|
114
|
+
@fingerprint ||= fingerprint_for(object)
|
115
|
+
end
|
116
|
+
|
117
|
+
def fingerprint_for(obj)
|
118
|
+
if obj.respond_to?(:fingerprint)
|
119
|
+
obj.fingerprint
|
120
|
+
else
|
121
|
+
Fingerprintable::Fingerprinter.new(object: obj).fingerprint
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
71
125
|
def instance_vars_with_readers
|
72
126
|
instance_variables = Hash[object.instance_variables.map { |e| [e, 1] }]
|
73
127
|
ret = object.class.instance_methods.select do |method|
|
@@ -76,18 +130,18 @@ module SimplySerializable
|
|
76
130
|
ret.map(&:to_sym)
|
77
131
|
end
|
78
132
|
|
79
|
-
def
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
cache.merge!(serializer.cache)
|
86
|
-
use_object_cache_key
|
133
|
+
def method_for_attribute(attr)
|
134
|
+
if object.class.instance_methods.include?("#{@method_prefix}_#{attr}".to_sym)
|
135
|
+
"#{@method_prefix}_#{attr}"
|
136
|
+
else
|
137
|
+
attr
|
138
|
+
end
|
87
139
|
end
|
88
140
|
|
89
|
-
def
|
90
|
-
|
141
|
+
def object_value_hash
|
142
|
+
Hash[attributes.map do |attr|
|
143
|
+
[attr, object.send(method_for_attribute(attr))]
|
144
|
+
end]
|
91
145
|
end
|
92
146
|
|
93
147
|
def populate_attributes
|
@@ -100,18 +154,32 @@ module SimplySerializable
|
|
100
154
|
attributes
|
101
155
|
end
|
102
156
|
|
103
|
-
def
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
157
|
+
def serialize_object(use_object)
|
158
|
+
use_object_cache_key = cache_key_for(use_object)
|
159
|
+
if @local_cache.key?(use_object_cache_key)
|
160
|
+
@nestable = false
|
161
|
+
return reference_to(use_object_cache_key)
|
108
162
|
end
|
163
|
+
serializer = unless use_object.respond_to?(:serialize)
|
164
|
+
raise "#{use_object.class.name} does not respond to serialize. Did you mean to include Serializable in this class?" unless @include_readable_instance_variables
|
165
|
+
|
166
|
+
Serializer.new(
|
167
|
+
cache: @local_cache,
|
168
|
+
object: use_object
|
169
|
+
)
|
170
|
+
else
|
171
|
+
use_object.serializer(cache: @local_cache)
|
172
|
+
end
|
173
|
+
serializer
|
174
|
+
@local_cache.merge!(serializer.cache)
|
175
|
+
reference_to(use_object_cache_key)
|
109
176
|
end
|
110
177
|
|
111
|
-
def
|
112
|
-
|
113
|
-
|
114
|
-
|
178
|
+
def reference_to(key)
|
179
|
+
{
|
180
|
+
object: :reference,
|
181
|
+
id: key
|
182
|
+
}
|
115
183
|
end
|
116
184
|
end
|
117
185
|
end
|
data/lib/simply_serializable.rb
CHANGED
@@ -4,4 +4,22 @@ require "simply_serializable/version"
|
|
4
4
|
require "simply_serializable/serializer"
|
5
5
|
require "simply_serializable/mixin"
|
6
6
|
|
7
|
-
module SimplySerializable
|
7
|
+
module SimplySerializable
|
8
|
+
class Error < StandardError
|
9
|
+
attr_reader :type
|
10
|
+
|
11
|
+
def initialize(message, type:)
|
12
|
+
@type = type
|
13
|
+
super(message)
|
14
|
+
end
|
15
|
+
|
16
|
+
class CircularDependencyError < Error
|
17
|
+
def initialize
|
18
|
+
super(
|
19
|
+
'Circular dependency detected',
|
20
|
+
type: :circular_dependency
|
21
|
+
)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: simply_serializable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Jackson
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-06-
|
11
|
+
date: 2019-06-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fingerprintable
|
@@ -103,7 +103,6 @@ executables: []
|
|
103
103
|
extensions: []
|
104
104
|
extra_rdoc_files: []
|
105
105
|
files:
|
106
|
-
- ".byebug_history"
|
107
106
|
- ".gitignore"
|
108
107
|
- ".rspec"
|
109
108
|
- ".travis.yml"
|
data/.byebug_history
DELETED