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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b0f8989f2a8520c25271107350edf070e2274d1fb17c48068f7c90394a907df4
4
- data.tar.gz: 9a65b5876a365b43b469e874a9429524e2dd5685207376e3ee4541bcf3c59047
3
+ metadata.gz: ed7754c68910d4556534b53f8475b8c36d1ad9259408508523c3bbd5463d0157
4
+ data.tar.gz: 39eb74d95beb65aee78582fba369bbe5bd76ef082ad9d5a5cedf28f5d738ceb3
5
5
  SHA512:
6
- metadata.gz: 5e7ea38a315a6d758ec707c99216f61b860252a47fbf0c93fa700967b331a0cefd9d3686b5397605322310d87e6b2dc4880ec7f6354139afbb0b43f0a514d700
7
- data.tar.gz: 2485f4b6be1560e14644fc6bfc03be00e65d6690202d3237af00f3ac0b6e0b2722a175cc1decbda2c106cd4870b7deef4f104b5c5bb879a991681e659e49d084
6
+ metadata.gz: 90156f91281bb1fdf486351962b3380ee430866feea4418f2644d72e07d4f60c3346459b7125e81e3141bdcd488e626be0aa4f9572782a9eb1b3dbd6d6f09f03
7
+ data.tar.gz: 455a807775db2e60c18f670e2c8ed080cd8995d3164c356e33897919c3af71315c26d21cdd038831f07246ca1c22acb1fe3873db1803d72f69420665392c0ab9
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- simply_serializable (1.2.2)
4
+ simply_serializable (1.3.0)
5
5
  fingerprintable (>= 1.2.1)
6
6
 
7
7
  GEM
@@ -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
- "#{serializable_type}/#{fingerprint}"
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
- @cache = cache
26
- @cache[cache_key] = nil
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
- serialize unless @serialized
34
- @cache
33
+ @cache ||= begin
34
+ serialize
35
+ @local_cache
36
+ end
35
37
  end
36
38
 
37
- def deep_serialize(obj)
38
- case obj
39
- when FalseClass, Float, nil, Integer, String, Symbol, TrueClass
40
- obj
41
- when Array
42
- obj.map { |v| deep_serialize(v) }
43
- when Hash
44
- Hash[obj.map { |k, v| [deep_serialize(k), deep_serialize(v)] }]
45
- when Module
46
- obj.name
47
- else
48
- serialize_object(obj)
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
- @serialized = true
58
+ @nestable = true
55
59
  ret = deep_serialize(object_value_hash)
56
60
 
57
- cache[cache_key] = ret
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: cache
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 serialize_object(use_object)
80
- use_object_cache_key = cache_key(use_object)
81
- return use_object_cache_key if cache.key?(use_object_cache_key)
82
- raise "#{use_object.class.name} does not respond to serialize. Did you mean to include Serializable in this class?" unless use_object.respond_to?(:serialize)
83
-
84
- serializer = use_object.serializer(cache: cache)
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 cache_key(obj = object)
90
- obj.serializable_id
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 method_for_attribute(attr)
104
- if object.class.instance_methods.include?("#{@method_prefix}_#{attr}".to_sym)
105
- "#{@method_prefix}_#{attr}"
106
- else
107
- attr
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 object_value_hash
112
- Hash[attributes.map do |attr|
113
- [attr, object.send(method_for_attribute(attr))]
114
- end]
178
+ def reference_to(key)
179
+ {
180
+ object: :reference,
181
+ id: key
182
+ }
115
183
  end
116
184
  end
117
185
  end
@@ -1,3 +1,3 @@
1
1
  module SimplySerializable
2
- VERSION = "1.2.2"
2
+ VERSION = "1.3.0"
3
3
  end
@@ -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; end
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.2.2
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-17 00:00:00.000000000 Z
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
@@ -1,21 +0,0 @@
1
- exit
2
- c
3
- serializable_config
4
- n
5
- serializable_config
6
- attributes
7
- c
8
- attributes
9
- pdb
10
- c
11
- attributes
12
- n
13
- except
14
- n
15
- only
16
- attributes
17
- n
18
- attributes
19
- n
20
- instance_vars_with_readers
21
- attributes