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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 443a464f8f7d09a40c3457933896eaa35a27c841db28a259dd6fd95edbf2ddd1
4
- data.tar.gz: 1ab61528123941c2d6905795ca0c9f5bc95dab2982635300344b0eabdd3d62d6
3
+ metadata.gz: 57d166375199eba26336a76a5fd98fdd3d434c2db20d08857f896137ae8c390a
4
+ data.tar.gz: 96aba9fff396a567ee408dad54c1485e39449a9258324fe811c62b98bc5fcf7a
5
5
  SHA512:
6
- metadata.gz: cbe8efbf120d930648abb69eca0b541ffe73181a2f63b1f0e0b4132506fb699e7a3b7007cf1f5c2e97415ef3936539222c282d7ea8766214b4a69e5c73b5d4b9
7
- data.tar.gz: 8f66f7174aa206a31c1b7885c2e1f2deae54fe882870db55017bef74363cae428bc8e14d20fcd925cca9cedb8041ef10349672a21feaf279a97577e4932d9cdb
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
@@ -13,3 +13,6 @@
13
13
  .rspec_status
14
14
  .rspec
15
15
  .history
16
+ /.vscode
17
+ .rubocop.yml
18
+ Gemfile.lock
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 'pry-byebug', '~> 3.7.0'
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', '~> 0.10.0'
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', '~> 0.17.1'
20
- gem 'benchmark-memory', '~> 0.1'
21
- gem 'rspec', '~> 3.0'
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.6 is **at least 5 times faster** than AMS (benchmarks was borrowed from fast_jsonapi repository)
13
- - running on ruby 2.6 it consumes **3 times less RAM**
14
- - running on jruby 9.2.7.0 **is at least 15 times faster** than AMS after warming up
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
 
@@ -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
- if obj.respond_to?(:dump) && obj.respond_to?(:load)
26
- @coder = obj
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
- @_config ||= Configuration.new
26
+ @config ||= Configuration.new
36
27
  end
37
28
 
38
29
  def configure(&block)
@@ -3,6 +3,10 @@
3
3
  module FastSerializer
4
4
  module JsonModel
5
5
  class Array < Relationship
6
+ # @param resource [Object]
7
+ # @param params [Hash]
8
+ # @param context [Hash]
9
+ # @return [Array]
6
10
  def serialize(resources, params, context)
7
11
  return if resources.nil?
8
12
 
@@ -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
- @method_name = "__#{key}__"
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 injected && !method_name.nil? && !context.nil?
63
- call_method_on_context(context, method_name, method_arity, resource, params)
64
-
65
- elsif method.is_a?(Proc)
66
- call_proc_binding_to_context(context, method, method_arity, resource, params)
67
-
68
- else
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
- res = if injected && !cond_method_name.nil? && !context.nil?
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
- def serialize(resource, params, context)
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 { |resource| @schema.serialize_resource(resource, params) }
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
- def serialize(resource, params, context)
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, context = nil)
22
+ def serialize(_resource, _params, _context = nil)
19
23
  raise NotImplementedError
20
24
  end
21
25
 
22
- def included?(_resource, _params, context = nil)
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
- res = attributes.values.each_with_object({}) do |attribute, res|
21
- next res unless attribute.included?(resource, params, context)
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
- res[attribute.key] = val
31
+ result[attribute.key] = val
25
32
  end
26
33
 
27
- res
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
- def initialize(key: nil, method: nil, opts: {}, serializer: nil, schema: nil, strict: false)
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
- raise ArgumentError, "must provide serializer or schema" if @serializer_klass.nil? && @schema.nil?
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
- params[:include_index].has_key?(key)
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__ = self.__schema__.deep_copy
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
- alias_method :object, :resource
42
+ alias object resource
30
43
 
31
44
  def serializable_hash(opts = {})
32
- self.params = params.merge(opts)
45
+ Utils.ref_merge(params, opts)
46
+ self.params = params
33
47
 
34
- if !self.class.__patched__
35
- injectable_attributes = self.class.__schema__.serialization_schema.attributes.select { |key, attribute| attribute.injectable? }
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
- self.params = params.merge(opts)
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 if !list
23
+ return unless list
24
+ return if list.empty?
28
25
 
29
- if list.any?
30
- @params[:include] = list.map(&:to_sym)
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 if !list
31
+ return unless list
32
+ return if list.empty?
37
33
 
38
- if list.any?
39
- @params[:exclude] = list.map(&:to_sym)
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
- # @param [Array] attribute_names
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 JsonModel::Attribute.new(
48
- key: attribute_name,
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
- # @param [String] attribute_name
55
- # @param [Hash] opts - attribute options
56
- # @param [Proc] block - result is used as the attribute value
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 JsonModel::Attribute.new(
59
- key: attribute_name,
60
- method: block,
61
- opts: opts,
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
- # @param [String] attribute_name
66
- # @param [Hash] opts - attribute options
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: opts.delete(:key) || attribute_name,
70
- method: opts.delete(:method) || attribute_name,
71
- opts: opts,
72
- schema: opts.delete(: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] attribute_name
80
- # @param [Hash] opts - attribute options
90
+ # @param attribute_name [String]
91
+ # @param opts [Hash] attribute options
81
92
  def has_many(attribute_name, opts = {})
82
- serialization_schema.add_attribute JsonModel::HasManyRelationship.new(
83
- key: opts.delete(:key) || attribute_name,
84
- method: opts.delete(:method) || attribute_name,
85
- opts: opts,
86
- schema: opts.delete(:schema),
87
- serializer: opts.delete(:serializer),
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 JsonModel::Array.new(
95
- key: attribute_name,
96
- method: attribute_name,
97
- opts: opts,
98
- schema: opts.delete(:schema),
99
- serializer: opts.delete(:serializer),
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
- _params_dup = FastSerializer::Utils.symbolize_keys(self.params.merge(params))
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 = resource.respond_to?(:size) && !resource.respond_to?(:each_pair)
123
- is_collection = params.delete(:is_collection) if params.has_key?(:is_collection)
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 = { root => res } if root && !root.empty?
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, _| res[key.to_sym] = hash[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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FastSerializer
4
- VERSION = '0.6.0'
4
+ VERSION = '0.6.5'
5
5
  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.0
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: 2020-02-01 00:00:00.000000000 Z
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.0.4
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