fast_serializer_ruby 0.6.0 → 0.6.5

Sign up to get free protection for your applications and to get access to all the features.
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