fast_serializer_ruby 0.6.0 → 0.6.5
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/.github/workflows/ruby.yml +42 -0
- data/.gitignore +3 -0
- data/Gemfile +11 -6
- data/README.md +3 -5
- data/fast_serializer.gemspec +1 -1
- data/lib/fast_serializer/configuration.rb +6 -15
- data/lib/fast_serializer/json_model/array.rb +4 -0
- data/lib/fast_serializer/json_model/attribute.rb +47 -39
- data/lib/fast_serializer/json_model/has_many_relationship.rb +5 -3
- data/lib/fast_serializer/json_model/has_one_relationship.rb +4 -1
- data/lib/fast_serializer/json_model/node.rb +6 -2
- data/lib/fast_serializer/json_model/object.rb +12 -4
- data/lib/fast_serializer/json_model/relationship.rb +20 -3
- data/lib/fast_serializer/schema/mixin.rb +22 -12
- data/lib/fast_serializer/schema.rb +70 -52
- data/lib/fast_serializer/utils.rb +9 -1
- data/lib/fast_serializer/version.rb +1 -1
- metadata +7 -8
- data/.travis.yml +0 -40
- data/Gemfile.lock +0 -125
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 57d166375199eba26336a76a5fd98fdd3d434c2db20d08857f896137ae8c390a
|
4
|
+
data.tar.gz: 96aba9fff396a567ee408dad54c1485e39449a9258324fe811c62b98bc5fcf7a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e2fbd568da824165230e83774d86a5765592fa03dd494fc9768050db593ce8dba32f257e0542159cdfff9d8756a355c9ca597f5752bd3170baa0092dc9fd1690
|
7
|
+
data.tar.gz: 13f090892e0d9dd7c97517d46512f2af0bedb5e9c0a1d0a4604da80da704c35c7c7b8276e873055ca15d4f20cd847ce9c6e20c8511ada38e39e49bf4a823266b
|
@@ -0,0 +1,42 @@
|
|
1
|
+
name: Ruby
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ master ]
|
6
|
+
pull_request:
|
7
|
+
branches: [ master ]
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
test:
|
11
|
+
runs-on: ubuntu-latest
|
12
|
+
strategy:
|
13
|
+
matrix:
|
14
|
+
ruby-version: ['2.3', '2.4', '2.5', '2.6', '2.7', 'jruby']
|
15
|
+
|
16
|
+
steps:
|
17
|
+
- uses: actions/checkout@v2
|
18
|
+
- uses: ruby/setup-ruby@473e4d8fe5dd94ee328fdfca9f8c9c7afc9dae5e
|
19
|
+
with:
|
20
|
+
ruby-version: ${{ matrix.ruby-version }}
|
21
|
+
bundler-cache: true
|
22
|
+
- run: bundle exec rspec --tag ~performance:true
|
23
|
+
|
24
|
+
coverage:
|
25
|
+
runs-on: ubuntu-latest
|
26
|
+
strategy:
|
27
|
+
matrix:
|
28
|
+
ruby-version: ['2.7']
|
29
|
+
steps:
|
30
|
+
- uses: actions/checkout@v2
|
31
|
+
- uses: ruby/setup-ruby@473e4d8fe5dd94ee328fdfca9f8c9c7afc9dae5e
|
32
|
+
with:
|
33
|
+
ruby-version: ${{ matrix.ruby-version }}
|
34
|
+
bundler-cache: true
|
35
|
+
- name: Test & publish code coverage
|
36
|
+
uses: paambaati/codeclimate-action@v2.7.5
|
37
|
+
with:
|
38
|
+
coverageCommand: bundle exec rspec --tag ~performance:true
|
39
|
+
env:
|
40
|
+
CC_TEST_REPORTER_ID: 99325a42b78ef51a9d51574d20dbcd6acdfe75c8568f1433f73b61f17149e05d
|
41
|
+
COVERAGE: 1
|
42
|
+
|
data/.gitignore
CHANGED
data/Gemfile
CHANGED
@@ -6,18 +6,23 @@ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
|
|
6
6
|
|
7
7
|
gemspec
|
8
8
|
|
9
|
-
group :development do
|
10
|
-
gem '
|
9
|
+
group :development, :test do
|
10
|
+
gem 'rake'
|
11
11
|
gem 'pry'
|
12
12
|
end
|
13
13
|
|
14
14
|
group :test do
|
15
|
-
gem 'active_model_serializers'
|
15
|
+
gem 'active_model_serializers'
|
16
16
|
gem 'factory_bot'
|
17
17
|
gem 'faker'
|
18
|
+
gem 'activesupport'
|
18
19
|
gem 'allocation_stats'
|
19
|
-
gem 'simplecov'
|
20
|
-
gem 'benchmark-memory'
|
21
|
-
gem 'rspec'
|
20
|
+
gem 'simplecov'
|
21
|
+
gem 'benchmark-memory'
|
22
|
+
gem 'rspec'
|
22
23
|
gem 'rspec-benchmark'
|
24
|
+
|
25
|
+
platform :mri do
|
26
|
+
gem 'pry-byebug'
|
27
|
+
end
|
23
28
|
end
|
data/README.md
CHANGED
@@ -9,9 +9,9 @@
|
|
9
9
|
This library intends to solve such a typical and on the other hand important problem as efficient ruby object to hash transformation.
|
10
10
|
|
11
11
|
## Performance 🚀
|
12
|
-
- running on ruby 2.
|
13
|
-
- running on ruby 2.
|
14
|
-
- running on jruby 9.2.7.0 **is at least
|
12
|
+
- running on ruby 2.7 is **at least 6 times faster** than AMS (benchmarks was borrowed from fast_jsonapi repository)
|
13
|
+
- running on ruby 2.7 it consumes **6 times less RAM**
|
14
|
+
- running on jruby 9.2.7.0 **is at least 4 times faster** than AMS after warming up
|
15
15
|
|
16
16
|
## Compatibility 👌
|
17
17
|
I tried to keep the API as close as possible to active_model_serializer implementation because we all got used to it.
|
@@ -106,8 +106,6 @@ schema.serializable_hash
|
|
106
106
|
}
|
107
107
|
}
|
108
108
|
|
109
|
-
|
110
|
-
|
111
109
|
```
|
112
110
|
|
113
111
|
|
data/fast_serializer.gemspec
CHANGED
@@ -14,7 +14,6 @@ Gem::Specification.new do |spec|
|
|
14
14
|
spec.description = 'This library intends to solve such a typical and on the other hand important problem as efficient ruby object to hash transformation.'
|
15
15
|
spec.homepage = 'https://github.com/estepnv/fast_serializer'
|
16
16
|
spec.license = 'MIT'
|
17
|
-
spec.platform = Gem::Platform::RUBY
|
18
17
|
spec.required_ruby_version = '>= 2.3.0'
|
19
18
|
|
20
19
|
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
@@ -33,6 +32,7 @@ Gem::Specification.new do |spec|
|
|
33
32
|
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
34
33
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{(test|spec|features|git|rspec|travis)/}) }
|
35
34
|
end
|
35
|
+
|
36
36
|
spec.bindir = 'bin'
|
37
37
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
38
38
|
spec.require_paths = ['lib']
|
@@ -4,35 +4,26 @@ require 'json'
|
|
4
4
|
|
5
5
|
module FastSerializer
|
6
6
|
class Configuration
|
7
|
-
|
8
|
-
RubyVer = Struct.new(:major, :feature, :fix) do
|
9
|
-
|
10
|
-
def is_2_4_or_less
|
11
|
-
major == 2 && feature <= 4
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
attr_reader :coder, :ruby_ver
|
7
|
+
attr_reader :coder
|
16
8
|
attr_accessor :strict
|
17
9
|
|
18
10
|
def initialize
|
19
11
|
@coder = JSON
|
20
12
|
@strict = false
|
21
|
-
@ruby_ver = RubyVer.new(*RUBY_VERSION.split(".").map(&:to_i))
|
22
13
|
end
|
23
14
|
|
24
15
|
def coder=(obj)
|
25
|
-
|
26
|
-
|
27
|
-
else
|
28
|
-
raise ArgumentError, "must respond to #load and #dump methods"
|
16
|
+
unless obj.respond_to?(:dump) && obj.respond_to?(:load)
|
17
|
+
raise ArgumentError, 'must respond to #load and #dump methods'
|
29
18
|
end
|
19
|
+
|
20
|
+
@coder = obj
|
30
21
|
end
|
31
22
|
end
|
32
23
|
|
33
24
|
class << self
|
34
25
|
def config
|
35
|
-
@
|
26
|
+
@config ||= Configuration.new
|
36
27
|
end
|
37
28
|
|
38
29
|
def configure(&block)
|
@@ -11,8 +11,9 @@ module FastSerializer
|
|
11
11
|
:cond_method_name,
|
12
12
|
:injected
|
13
13
|
|
14
|
-
def initialize(
|
14
|
+
def initialize(*)
|
15
15
|
super
|
16
|
+
|
16
17
|
@mixin = nil
|
17
18
|
@method_name = nil
|
18
19
|
@injected = false
|
@@ -20,32 +21,8 @@ module FastSerializer
|
|
20
21
|
@cond = nil
|
21
22
|
@cond = @opts[:if] || @opts[:unless] || @cond
|
22
23
|
|
23
|
-
if method.is_a?(Proc)
|
24
|
-
|
25
|
-
@method_arity = method.arity.abs
|
26
|
-
@mixin = Module.new
|
27
|
-
|
28
|
-
if FastSerializer.config.ruby_ver.is_2_4_or_less
|
29
|
-
@mixin.redefine_method @method_name, &method
|
30
|
-
else
|
31
|
-
@mixin.define_method @method_name, &method
|
32
|
-
end
|
33
|
-
|
34
|
-
end
|
35
|
-
|
36
|
-
if !cond.nil? && cond.is_a?(Proc)
|
37
|
-
@cond_method_name = "__#{key}_cond__"
|
38
|
-
@cond_arity = cond.arity.abs
|
39
|
-
@mixin ||= Module.new
|
40
|
-
|
41
|
-
if FastSerializer.config.ruby_ver.is_2_4_or_less
|
42
|
-
@mixin.redefine_method @cond_method_name, &cond
|
43
|
-
else
|
44
|
-
@mixin.define_method @cond_method_name, &cond
|
45
|
-
end
|
46
|
-
|
47
|
-
end
|
48
|
-
|
24
|
+
init_with_proc if method.is_a?(Proc)
|
25
|
+
init_with_cond if !cond.nil? && cond.is_a?(Proc)
|
49
26
|
end
|
50
27
|
|
51
28
|
def injectable?
|
@@ -57,32 +34,39 @@ module FastSerializer
|
|
57
34
|
self.injected = true
|
58
35
|
end
|
59
36
|
|
37
|
+
# @param resource [Object]
|
38
|
+
# @param params [Hash]
|
39
|
+
# @param context [Hash]
|
40
|
+
# @return [Object]
|
60
41
|
def serialize(resource, params, context)
|
42
|
+
can_execute_on_mixin = injected && !method_name.nil? && !context.nil?
|
61
43
|
|
62
|
-
val = if
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
resource.public_send(method)
|
70
|
-
end
|
44
|
+
val = if can_execute_on_mixin
|
45
|
+
call_method_on_context(context, method_name, method_arity, resource, params)
|
46
|
+
elsif method.is_a?(Proc)
|
47
|
+
call_proc_binding_to_context(context, method, method_arity, resource, params)
|
48
|
+
else
|
49
|
+
resource.public_send(method)
|
50
|
+
end
|
71
51
|
|
72
52
|
val.freeze
|
73
53
|
|
74
54
|
val
|
75
55
|
end
|
76
56
|
|
57
|
+
# @param resource [Object]
|
58
|
+
# @param params [Hash]
|
59
|
+
# @param context [Hash]
|
60
|
+
# @return [Boolean]
|
77
61
|
def included?(resource, params, context)
|
78
62
|
return true if cond.nil?
|
79
63
|
|
80
|
-
|
81
|
-
call_method_on_context(context, cond_method_name, cond_arity, resource, params)
|
64
|
+
can_execute_on_mixin = injected && !cond_method_name.nil? && !context.nil?
|
82
65
|
|
66
|
+
res = if can_execute_on_mixin
|
67
|
+
call_method_on_context(context, cond_method_name, cond_arity, resource, params)
|
83
68
|
elsif cond.is_a?(Proc)
|
84
69
|
call_proc_binding_to_context(context, cond, cond_arity, resource, params)
|
85
|
-
|
86
70
|
else
|
87
71
|
context.public_send(cond)
|
88
72
|
end
|
@@ -94,6 +78,30 @@ module FastSerializer
|
|
94
78
|
|
95
79
|
private
|
96
80
|
|
81
|
+
def init_with_cond
|
82
|
+
@cond_method_name = "__#{key}_cond__"
|
83
|
+
@cond_arity = cond.arity.abs
|
84
|
+
@mixin ||= Module.new
|
85
|
+
|
86
|
+
if RUBY_VERSION <= '2.5.0'
|
87
|
+
@mixin.redefine_method @cond_method_name, &cond
|
88
|
+
else
|
89
|
+
@mixin.define_method @cond_method_name, &cond
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def init_with_proc
|
94
|
+
@method_name = "__#{key}__"
|
95
|
+
@method_arity = method.arity.abs
|
96
|
+
@mixin = Module.new
|
97
|
+
|
98
|
+
if RUBY_VERSION <= '2.5.0'
|
99
|
+
@mixin.redefine_method @method_name, &method
|
100
|
+
else
|
101
|
+
@mixin.define_method @method_name, &method
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
97
105
|
def call_proc_binding_to_context(context, prc, arity, resource, params)
|
98
106
|
case arity
|
99
107
|
when 1
|
@@ -3,16 +3,18 @@
|
|
3
3
|
module FastSerializer
|
4
4
|
module JsonModel
|
5
5
|
class HasManyRelationship < Relationship
|
6
|
-
|
6
|
+
# @param resource [Object]
|
7
|
+
# @param params [Hash]
|
8
|
+
# @return [Array<Hash>]
|
9
|
+
def serialize(resource, params, _context)
|
7
10
|
collection = resource.public_send(method)
|
8
11
|
return if collection.nil?
|
9
12
|
|
10
13
|
if @serializer_klass
|
11
14
|
@serializer_klass.new(collection, params).serializable_hash
|
12
15
|
elsif @schema
|
13
|
-
collection.map { |
|
16
|
+
collection.map { |entry| @schema.serialize_resource(entry, params) }
|
14
17
|
end
|
15
|
-
|
16
18
|
end
|
17
19
|
end
|
18
20
|
end
|
@@ -3,7 +3,10 @@
|
|
3
3
|
module FastSerializer
|
4
4
|
module JsonModel
|
5
5
|
class HasOneRelationship < Relationship
|
6
|
-
|
6
|
+
# @param resource [Object]
|
7
|
+
# @param params [Hash]
|
8
|
+
# @return [Hash]
|
9
|
+
def serialize(resource, params, _)
|
7
10
|
relation = resource.public_send(method)
|
8
11
|
|
9
12
|
if @serializer_klass
|
@@ -5,21 +5,25 @@ module FastSerializer
|
|
5
5
|
class Node
|
6
6
|
attr_accessor :key, :method, :context
|
7
7
|
|
8
|
+
# @param key [String]
|
9
|
+
# @param method [String]
|
10
|
+
# @param opts [Hash]
|
8
11
|
def initialize(key: nil, method: nil, opts: {}, **_)
|
9
12
|
@key = key&.to_sym
|
10
13
|
@method = method || key
|
11
14
|
@opts = opts || {}
|
12
15
|
end
|
13
16
|
|
17
|
+
# @return [Boolean]
|
14
18
|
def injectable?
|
15
19
|
false
|
16
20
|
end
|
17
21
|
|
18
|
-
def serialize(_resource, _params,
|
22
|
+
def serialize(_resource, _params, _context = nil)
|
19
23
|
raise NotImplementedError
|
20
24
|
end
|
21
25
|
|
22
|
-
def included?(_resource, _params,
|
26
|
+
def included?(_resource, _params, _context = nil)
|
23
27
|
raise NotImplementedError
|
24
28
|
end
|
25
29
|
end
|
@@ -10,23 +10,31 @@ module FastSerializer
|
|
10
10
|
@attributes = {}
|
11
11
|
end
|
12
12
|
|
13
|
+
# @param attribute [FastSerializer::JsonModel::Node]
|
13
14
|
def add_attribute(attribute)
|
14
15
|
attributes[attribute.key] = attribute
|
15
16
|
end
|
16
17
|
|
18
|
+
# @param resource [Object]
|
19
|
+
# @param params [Hash]
|
20
|
+
# @param context [Hash]
|
21
|
+
# @return [Hash]
|
17
22
|
def serialize(resource, params, context)
|
18
23
|
return if resource.nil?
|
19
24
|
|
20
|
-
|
21
|
-
|
25
|
+
result = {}
|
26
|
+
|
27
|
+
attributes.each do |_, attribute|
|
28
|
+
next unless attribute.included?(resource, params, context)
|
22
29
|
|
23
30
|
val = attribute.serialize(resource, params, context)
|
24
|
-
|
31
|
+
result[attribute.key] = val
|
25
32
|
end
|
26
33
|
|
27
|
-
|
34
|
+
result
|
28
35
|
end
|
29
36
|
|
37
|
+
# @return [Boolean]
|
30
38
|
def included?(*)
|
31
39
|
true
|
32
40
|
end
|
@@ -5,32 +5,49 @@ module FastSerializer
|
|
5
5
|
class Relationship < Attribute
|
6
6
|
attr_accessor :serialization_schema
|
7
7
|
|
8
|
-
|
8
|
+
# @param serializer [FastSerializer::Schema::Mixin]
|
9
|
+
# @param schema [FastSerializer::Schema]
|
10
|
+
def initialize(serializer: nil, schema: nil, **)
|
9
11
|
super
|
12
|
+
|
10
13
|
@serializer_klass = serializer
|
11
14
|
@schema = schema
|
12
15
|
|
13
|
-
|
16
|
+
if @serializer_klass.nil? && @schema.nil?
|
17
|
+
raise ArgumentError, 'must provide serializer or schema'
|
18
|
+
end
|
14
19
|
end
|
15
20
|
|
21
|
+
# @param resource [Object]
|
22
|
+
# @param params [Hash]
|
23
|
+
# @param context [Hash]
|
24
|
+
# @return [Boolean]
|
16
25
|
def included?(resource, params, context)
|
17
26
|
super && include_relation?(params)
|
18
27
|
end
|
19
28
|
|
29
|
+
# @param params [Hash]
|
30
|
+
# @return [Boolean]
|
20
31
|
def include_relation?(params)
|
21
32
|
include?(params) && !exclude?(params)
|
22
33
|
end
|
23
34
|
|
35
|
+
# @param params [Hash]
|
36
|
+
# @return [Boolean]
|
24
37
|
def exclude?(params)
|
25
38
|
return false if params[:exclude].nil?
|
26
39
|
return false if params[:exclude].empty?
|
40
|
+
|
27
41
|
params[:exclude_index].key?(key)
|
28
42
|
end
|
29
43
|
|
44
|
+
# @param params [Hash]
|
45
|
+
# @return [Boolean]
|
30
46
|
def include?(params)
|
31
47
|
return true if params[:include].nil?
|
32
48
|
return false if params[:include].empty?
|
33
|
-
|
49
|
+
|
50
|
+
params[:include_index].key?(key)
|
34
51
|
end
|
35
52
|
end
|
36
53
|
end
|
@@ -1,12 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module FastSerializer
|
2
4
|
class Schema
|
3
5
|
module Mixin
|
4
|
-
|
5
6
|
module ClassMethods
|
6
7
|
attr_accessor :__schema__, :__patched__
|
7
8
|
|
8
9
|
def inherited(subclass)
|
9
|
-
subclass.__schema__ =
|
10
|
+
subclass.__schema__ = __schema__.deep_copy
|
10
11
|
end
|
11
12
|
|
12
13
|
def method_missing(method, *args, &block)
|
@@ -16,6 +17,18 @@ module FastSerializer
|
|
16
17
|
super
|
17
18
|
end
|
18
19
|
end
|
20
|
+
|
21
|
+
def respond_to_missing?(method_name, include_private = false)
|
22
|
+
__schema__.respond_to?(method_name) || super
|
23
|
+
end
|
24
|
+
|
25
|
+
def __patch_with_attribute_definition
|
26
|
+
injectable_attributes = __schema__.serialization_schema.attributes.select { |_key, attribute| attribute.injectable? }
|
27
|
+
injectable_attributes.each { |_, attribute| attribute.inject(self) }
|
28
|
+
self.__patched__ = true
|
29
|
+
|
30
|
+
__patched__.freeze
|
31
|
+
end
|
19
32
|
end
|
20
33
|
|
21
34
|
module InstanceMethods
|
@@ -26,24 +39,21 @@ module FastSerializer
|
|
26
39
|
self.params = params || {}
|
27
40
|
end
|
28
41
|
|
29
|
-
|
42
|
+
alias object resource
|
30
43
|
|
31
44
|
def serializable_hash(opts = {})
|
32
|
-
|
45
|
+
Utils.ref_merge(params, opts)
|
46
|
+
self.params = params
|
33
47
|
|
34
|
-
|
35
|
-
|
36
|
-
injectable_attributes.each { |key, attribute| attribute.inject(self.class) }
|
37
|
-
self.class.__patched__ = true
|
38
|
-
self.class.__patched__.freeze
|
48
|
+
unless self.class.__patched__
|
49
|
+
self.class.__patch_with_attribute_definition
|
39
50
|
end
|
40
51
|
|
41
52
|
self.class.__schema__.serialize_resource(resource, params, self)
|
42
53
|
end
|
43
54
|
|
44
55
|
def serialized_json(opts = {})
|
45
|
-
|
46
|
-
self.class.__schema__.serialize_resource_to_json(resource, params, self)
|
56
|
+
FastSerializer.config.coder.dump(serializable_hash(opts))
|
47
57
|
end
|
48
58
|
|
49
59
|
alias as_json serializable_hash
|
@@ -57,4 +67,4 @@ module FastSerializer
|
|
57
67
|
end
|
58
68
|
end
|
59
69
|
end
|
60
|
-
end
|
70
|
+
end
|
@@ -3,13 +3,9 @@
|
|
3
3
|
require 'forwardable'
|
4
4
|
|
5
5
|
module FastSerializer
|
6
|
-
|
7
6
|
class Schema
|
8
|
-
|
9
7
|
attr_reader :_root, :serialization_schema, :params, :strict
|
10
8
|
|
11
|
-
public
|
12
|
-
|
13
9
|
def initialize(params = {}, root = nil, strict = nil)
|
14
10
|
@root = root
|
15
11
|
@strict = strict || FastSerializer.config.strict
|
@@ -24,79 +20,98 @@ module FastSerializer
|
|
24
20
|
end
|
25
21
|
|
26
22
|
def include=(list)
|
27
|
-
return
|
23
|
+
return unless list
|
24
|
+
return if list.empty?
|
28
25
|
|
29
|
-
|
30
|
-
|
31
|
-
@params[:include_index] = @params[:include].map { |key| [key, nil] }.to_h
|
32
|
-
end
|
26
|
+
@params[:include] = list.map(&:to_sym)
|
27
|
+
@params[:include_index] = @params[:include].map { |key| [key, nil] }.to_h
|
33
28
|
end
|
34
29
|
|
35
30
|
def exclude=(list)
|
36
|
-
return
|
31
|
+
return unless list
|
32
|
+
return if list.empty?
|
37
33
|
|
38
|
-
|
39
|
-
|
40
|
-
@params[:exclude_index] = @params[:exclude].map { |key| [key, nil] }.to_h
|
41
|
-
end
|
34
|
+
@params[:exclude] = list.map(&:to_sym)
|
35
|
+
@params[:exclude_index] = @params[:exclude].map { |key| [key, nil] }.to_h
|
42
36
|
end
|
43
37
|
|
44
|
-
#
|
38
|
+
# Defines a list of attributes for serialization
|
39
|
+
#
|
40
|
+
# @param attribute_names [Array<String, Symbol>] a list of attributes to serialize
|
41
|
+
# each of these attributes value is fetched calling a corresponding method from a resource instance
|
42
|
+
# passed to the serializer
|
45
43
|
def attributes(*attribute_names)
|
46
44
|
attribute_names.each do |attribute_name|
|
47
|
-
serialization_schema.add_attribute
|
48
|
-
key:
|
49
|
-
method: attribute_name,
|
45
|
+
serialization_schema.add_attribute(
|
46
|
+
JsonModel::Attribute.new(key: attribute_name, method: attribute_name)
|
50
47
|
)
|
51
48
|
end
|
52
49
|
end
|
53
50
|
|
54
|
-
#
|
55
|
-
#
|
56
|
-
# @param [
|
51
|
+
# Defines an attribute for serialization
|
52
|
+
#
|
53
|
+
# @param attribute_name [String, Symbol] an attribute name
|
54
|
+
# @param opts [Hash] attribute options
|
55
|
+
# @option opts [Proc] :if conditional clause. accepts a proc/lambda which has to return a boolean
|
56
|
+
# @option opts [Proc] :unless (see opts:if)
|
57
|
+
# @param block [Proc] result is used as the attribute value
|
58
|
+
#
|
57
59
|
def attribute(attribute_name, opts = {}, &block)
|
58
|
-
serialization_schema.add_attribute
|
59
|
-
|
60
|
-
|
61
|
-
|
60
|
+
serialization_schema.add_attribute(
|
61
|
+
JsonModel::Attribute.new(
|
62
|
+
key: attribute_name,
|
63
|
+
method: block,
|
64
|
+
opts: opts
|
65
|
+
)
|
62
66
|
)
|
63
67
|
end
|
64
68
|
|
65
|
-
#
|
66
|
-
#
|
69
|
+
# Defines an attribute for serialization
|
70
|
+
#
|
71
|
+
# @param attribute_name [String, Symbol] an attribute name
|
72
|
+
# @param opts [Hash] attribute options
|
73
|
+
# @option opts [Proc] :if conditional clause. accepts a proc/lambda which has to return a boolean
|
74
|
+
# @option opts [Proc] :unless (see opts:if)
|
75
|
+
# @option opts [FastSerializer::Schema::Mixin, nil] :serializer a serializer class with injected module or a inherited class
|
76
|
+
# @option opts [FastSerializer::Schema] :schema
|
77
|
+
#
|
67
78
|
def has_one(attribute_name, opts = {})
|
68
79
|
serialization_schema.add_attribute JsonModel::HasOneRelationship.new(
|
69
|
-
key:
|
70
|
-
method:
|
71
|
-
opts:
|
72
|
-
schema:
|
73
|
-
serializer: opts.delete(:serializer)
|
80
|
+
key: opts.delete(:key) || attribute_name,
|
81
|
+
method: opts.delete(:method) || attribute_name,
|
82
|
+
opts: opts,
|
83
|
+
schema: opts.delete(:schema),
|
84
|
+
serializer: opts.delete(:serializer)
|
74
85
|
)
|
75
86
|
end
|
76
87
|
|
77
88
|
alias belongs_to has_one
|
78
89
|
|
79
|
-
# @param [String]
|
80
|
-
# @param [Hash]
|
90
|
+
# @param attribute_name [String]
|
91
|
+
# @param opts [Hash] attribute options
|
81
92
|
def has_many(attribute_name, opts = {})
|
82
|
-
serialization_schema.add_attribute
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
93
|
+
serialization_schema.add_attribute(
|
94
|
+
JsonModel::HasManyRelationship.new(
|
95
|
+
key: opts.delete(:key) || attribute_name,
|
96
|
+
method: opts.delete(:method) || attribute_name,
|
97
|
+
opts: opts,
|
98
|
+
schema: opts.delete(:schema),
|
99
|
+
serializer: opts.delete(:serializer)
|
100
|
+
)
|
88
101
|
)
|
89
102
|
end
|
90
103
|
|
91
104
|
# @param [String] attribute_name
|
92
105
|
# @param [Hash] opts - attribute options
|
93
106
|
def list(attribute_name, opts = {})
|
94
|
-
serialization_schema.add_attribute
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
107
|
+
serialization_schema.add_attribute(
|
108
|
+
JsonModel::Array.new(
|
109
|
+
key: attribute_name,
|
110
|
+
method: attribute_name,
|
111
|
+
opts: opts,
|
112
|
+
schema: opts.delete(:schema),
|
113
|
+
serializer: opts.delete(:serializer)
|
114
|
+
)
|
100
115
|
)
|
101
116
|
end
|
102
117
|
|
@@ -116,11 +131,16 @@ module FastSerializer
|
|
116
131
|
end
|
117
132
|
|
118
133
|
def serialize_resource(resource, params = {}, context = self)
|
119
|
-
|
134
|
+
Utils.ref_merge(self.params, params)
|
135
|
+
_params_dup = FastSerializer::Utils.symbolize_keys(self.params)
|
120
136
|
meta = _params_dup.delete(:meta)
|
121
137
|
|
122
|
-
is_collection =
|
123
|
-
|
138
|
+
is_collection = if _params_dup.key?(:is_collection)
|
139
|
+
_params_dup.delete(:is_collection)
|
140
|
+
params.delete(:is_collection)
|
141
|
+
else
|
142
|
+
resource.respond_to?(:each) && !resource.respond_to?(:each_pair)
|
143
|
+
end
|
124
144
|
|
125
145
|
root = (_root || _params_dup.delete(:root))
|
126
146
|
|
@@ -134,12 +154,10 @@ module FastSerializer
|
|
134
154
|
end
|
135
155
|
|
136
156
|
else
|
137
|
-
|
138
157
|
serialization_schema.serialize(resource, _params_dup, context)
|
139
|
-
|
140
158
|
end
|
141
159
|
|
142
|
-
res
|
160
|
+
res = { root => res } if root && !root.empty?
|
143
161
|
|
144
162
|
res[:meta] = meta if res.is_a?(Hash) && meta
|
145
163
|
|
@@ -1,9 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module FastSerializer
|
2
4
|
module Utils
|
3
5
|
def self.symbolize_keys(hash)
|
4
6
|
res = {}
|
5
|
-
hash.each { |key,
|
7
|
+
hash.each { |key, value| res[key.to_sym] = value }
|
6
8
|
hash
|
7
9
|
end
|
10
|
+
|
11
|
+
def self.ref_merge(hash_a, hash_b)
|
12
|
+
hash_b.each do |key, value|
|
13
|
+
hash_a[key] = value
|
14
|
+
end
|
15
|
+
end
|
8
16
|
end
|
9
17
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fast_serializer_ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Evgeny Stepanov
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-11-13 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: This library intends to solve such a typical and on the other hand important
|
14
14
|
problem as efficient ruby object to hash transformation.
|
@@ -18,12 +18,11 @@ executables: []
|
|
18
18
|
extensions: []
|
19
19
|
extra_rdoc_files: []
|
20
20
|
files:
|
21
|
+
- ".github/workflows/ruby.yml"
|
21
22
|
- ".gitignore"
|
22
|
-
- ".travis.yml"
|
23
23
|
- CHANGELOG.md
|
24
24
|
- CODE_OF_CONDUCT.md
|
25
25
|
- Gemfile
|
26
|
-
- Gemfile.lock
|
27
26
|
- LICENSE.txt
|
28
27
|
- README.md
|
29
28
|
- Rakefile
|
@@ -51,7 +50,7 @@ metadata:
|
|
51
50
|
homepage_uri: https://github.com/estepnv/fast_serializer
|
52
51
|
source_code_uri: https://github.com/estepnv/fast_serializer
|
53
52
|
changelog_uri: https://github.com/estepnv/fast_serializer/CHANGELOG.md
|
54
|
-
post_install_message:
|
53
|
+
post_install_message:
|
55
54
|
rdoc_options: []
|
56
55
|
require_paths:
|
57
56
|
- lib
|
@@ -66,8 +65,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
66
65
|
- !ruby/object:Gem::Version
|
67
66
|
version: '0'
|
68
67
|
requirements: []
|
69
|
-
rubygems_version: 3.
|
70
|
-
signing_key:
|
68
|
+
rubygems_version: 3.2.27
|
69
|
+
signing_key:
|
71
70
|
specification_version: 4
|
72
71
|
summary: fast_serializer is a lightweight ruby objects serializer.
|
73
72
|
test_files: []
|
data/.travis.yml
DELETED
@@ -1,40 +0,0 @@
|
|
1
|
-
sudo: false
|
2
|
-
|
3
|
-
language: ruby
|
4
|
-
|
5
|
-
rvm:
|
6
|
-
- 2.3
|
7
|
-
- 2.4
|
8
|
-
- 2.5
|
9
|
-
- 2.6
|
10
|
-
- 2.7
|
11
|
-
- jruby-9.2.0.0
|
12
|
-
- ruby-head
|
13
|
-
- jruby-head
|
14
|
-
|
15
|
-
matrix:
|
16
|
-
allow_failures:
|
17
|
-
- rvm: jruby-9.2.0.0
|
18
|
-
- rvm: ruby-head
|
19
|
-
- rvm: jruby-head
|
20
|
-
|
21
|
-
before_install:
|
22
|
-
- yes | gem update --system --force
|
23
|
-
- gem install bundler
|
24
|
-
|
25
|
-
before_script:
|
26
|
-
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
27
|
-
- chmod +x ./cc-test-reporter
|
28
|
-
- ./cc-test-reporter before-build
|
29
|
-
|
30
|
-
script: bundle exec rspec --tag ~performance:true
|
31
|
-
|
32
|
-
after_script:
|
33
|
-
- ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
|
34
|
-
|
35
|
-
cache: bundler
|
36
|
-
|
37
|
-
env:
|
38
|
-
global:
|
39
|
-
CC_TEST_REPORTER_ID=99325a42b78ef51a9d51574d20dbcd6acdfe75c8568f1433f73b61f17149e05d
|
40
|
-
COVERAGE=1
|
data/Gemfile.lock
DELETED
@@ -1,125 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
fast_serializer_ruby (0.6.0)
|
5
|
-
|
6
|
-
GEM
|
7
|
-
remote: https://rubygems.org/
|
8
|
-
specs:
|
9
|
-
actionpack (5.2.4.1)
|
10
|
-
actionview (= 5.2.4.1)
|
11
|
-
activesupport (= 5.2.4.1)
|
12
|
-
rack (~> 2.0, >= 2.0.8)
|
13
|
-
rack-test (>= 0.6.3)
|
14
|
-
rails-dom-testing (~> 2.0)
|
15
|
-
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
16
|
-
actionview (5.2.4.1)
|
17
|
-
activesupport (= 5.2.4.1)
|
18
|
-
builder (~> 3.1)
|
19
|
-
erubi (~> 1.4)
|
20
|
-
rails-dom-testing (~> 2.0)
|
21
|
-
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
22
|
-
active_model_serializers (0.10.10)
|
23
|
-
actionpack (>= 4.1, < 6.1)
|
24
|
-
activemodel (>= 4.1, < 6.1)
|
25
|
-
case_transform (>= 0.2)
|
26
|
-
jsonapi-renderer (>= 0.1.1.beta1, < 0.3)
|
27
|
-
activemodel (5.2.4.1)
|
28
|
-
activesupport (= 5.2.4.1)
|
29
|
-
activesupport (5.2.4.1)
|
30
|
-
concurrent-ruby (~> 1.0, >= 1.0.2)
|
31
|
-
i18n (>= 0.7, < 2)
|
32
|
-
minitest (~> 5.1)
|
33
|
-
tzinfo (~> 1.1)
|
34
|
-
allocation_stats (0.1.5)
|
35
|
-
benchmark-malloc (0.1.0)
|
36
|
-
benchmark-memory (0.1.2)
|
37
|
-
memory_profiler (~> 0.9)
|
38
|
-
benchmark-perf (0.5.0)
|
39
|
-
benchmark-trend (0.3.0)
|
40
|
-
builder (3.2.4)
|
41
|
-
byebug (11.0.1)
|
42
|
-
case_transform (0.2)
|
43
|
-
activesupport
|
44
|
-
coderay (1.1.2)
|
45
|
-
concurrent-ruby (1.1.5)
|
46
|
-
crass (1.0.6)
|
47
|
-
diff-lcs (1.3)
|
48
|
-
docile (1.3.2)
|
49
|
-
erubi (1.9.0)
|
50
|
-
factory_bot (5.1.1)
|
51
|
-
activesupport (>= 4.2.0)
|
52
|
-
faker (2.10.1)
|
53
|
-
i18n (>= 1.6, < 2)
|
54
|
-
i18n (1.8.2)
|
55
|
-
concurrent-ruby (~> 1.0)
|
56
|
-
json (2.3.0)
|
57
|
-
jsonapi-renderer (0.2.2)
|
58
|
-
loofah (2.4.0)
|
59
|
-
crass (~> 1.0.2)
|
60
|
-
nokogiri (>= 1.5.9)
|
61
|
-
memory_profiler (0.9.14)
|
62
|
-
method_source (0.9.2)
|
63
|
-
mini_portile2 (2.4.0)
|
64
|
-
minitest (5.14.0)
|
65
|
-
nokogiri (1.10.7)
|
66
|
-
mini_portile2 (~> 2.4.0)
|
67
|
-
pry (0.12.2)
|
68
|
-
coderay (~> 1.1.0)
|
69
|
-
method_source (~> 0.9.0)
|
70
|
-
pry-byebug (3.7.0)
|
71
|
-
byebug (~> 11.0)
|
72
|
-
pry (~> 0.10)
|
73
|
-
rack (2.1.2)
|
74
|
-
rack-test (1.1.0)
|
75
|
-
rack (>= 1.0, < 3)
|
76
|
-
rails-dom-testing (2.0.3)
|
77
|
-
activesupport (>= 4.2.0)
|
78
|
-
nokogiri (>= 1.6)
|
79
|
-
rails-html-sanitizer (1.3.0)
|
80
|
-
loofah (~> 2.3)
|
81
|
-
rspec (3.9.0)
|
82
|
-
rspec-core (~> 3.9.0)
|
83
|
-
rspec-expectations (~> 3.9.0)
|
84
|
-
rspec-mocks (~> 3.9.0)
|
85
|
-
rspec-benchmark (0.5.1)
|
86
|
-
benchmark-malloc (~> 0.1.0)
|
87
|
-
benchmark-perf (~> 0.5.0)
|
88
|
-
benchmark-trend (~> 0.3.0)
|
89
|
-
rspec (>= 3.0.0, < 4.0.0)
|
90
|
-
rspec-core (3.9.1)
|
91
|
-
rspec-support (~> 3.9.1)
|
92
|
-
rspec-expectations (3.9.0)
|
93
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
94
|
-
rspec-support (~> 3.9.0)
|
95
|
-
rspec-mocks (3.9.1)
|
96
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
97
|
-
rspec-support (~> 3.9.0)
|
98
|
-
rspec-support (3.9.2)
|
99
|
-
simplecov (0.17.1)
|
100
|
-
docile (~> 1.1)
|
101
|
-
json (>= 1.8, < 3)
|
102
|
-
simplecov-html (~> 0.10.0)
|
103
|
-
simplecov-html (0.10.2)
|
104
|
-
thread_safe (0.3.6)
|
105
|
-
tzinfo (1.2.6)
|
106
|
-
thread_safe (~> 0.1)
|
107
|
-
|
108
|
-
PLATFORMS
|
109
|
-
ruby
|
110
|
-
|
111
|
-
DEPENDENCIES
|
112
|
-
active_model_serializers (~> 0.10.0)
|
113
|
-
allocation_stats
|
114
|
-
benchmark-memory (~> 0.1)
|
115
|
-
factory_bot
|
116
|
-
faker
|
117
|
-
fast_serializer_ruby!
|
118
|
-
pry
|
119
|
-
pry-byebug (~> 3.7.0)
|
120
|
-
rspec (~> 3.0)
|
121
|
-
rspec-benchmark
|
122
|
-
simplecov (~> 0.17.1)
|
123
|
-
|
124
|
-
BUNDLED WITH
|
125
|
-
2.1.4
|