alba 0.11.0 → 0.11.1

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: f9adc72b171ef6c74c4198ddad4cc8f629c416c62c6b8d8a9698efdbe9dccc44
4
- data.tar.gz: af33f05822bfee2bdfe455d4b7a9e75b0e2486c692297e24ab28768c0a839b24
3
+ metadata.gz: 9aae01860e12e1e5fd71f066e8772fb3a80b4aec6e99cf9dd55ad8652896ea24
4
+ data.tar.gz: c9930853dcaaa5ea2ff28e954c3b0d7e2ba559efc64b82e7da6b0c28968f55ed
5
5
  SHA512:
6
- metadata.gz: 2b289f590bf7b4cc3682b13f7841e9408f61ba7d49c0521b05649fb658745cd76c91032f3c2ee83224a1407f17686dc01eb383d90219877ac6f077b05095ce4c
7
- data.tar.gz: f842f9775b8355ed1b0dd88ea14aaecd57699fc578a11c38bf3a3d12ad04bbf01dbe0867bb30efc4cc73f1e7766d6e0e0e750741c6130dd33562434bfea6ba8b
6
+ metadata.gz: 7882b0950c339f87fc75b19e79bcdc2481a296331e9be47a646db997fa4db5639af31c49d529063d099cd5df405357d245397af23b0038c568e32feb86bd5718
7
+ data.tar.gz: 2bc8c03f0ca5049a23b7dd5c2f6582051f98296a0ba9e0a436e08e9a426a53896e7ac94af276cc3a82e5a0a253f30d381db5384e483c77918ff3d5ef9165a1b7
@@ -18,9 +18,6 @@ AllCops:
18
18
  Bundler/GemComment:
19
19
  Enabled: false
20
20
 
21
- Layout/ClassStructure:
22
- Enabled: true
23
-
24
21
  Layout/SpaceInsideHashLiteralBraces:
25
22
  EnforcedStyle: no_space
26
23
 
@@ -38,14 +35,12 @@ Metrics/MethodLength:
38
35
  Max: 15
39
36
 
40
37
  Style/ConstantVisibility:
41
- Enabled: false
38
+ Exclude:
39
+ - 'lib/alba/version.rb'
42
40
 
43
41
  Style/Copyright:
44
42
  Enabled: false
45
43
 
46
- Style/DocumentationMethod:
47
- Enabled: false
48
-
49
44
  Style/FrozenStringLiteralComment:
50
45
  Enabled: false
51
46
 
@@ -5,5 +5,6 @@ rvm:
5
5
  - 2.5.8
6
6
  - 2.6.6
7
7
  - 2.7.1
8
+ # - ruby-head # oj doesn't work with Ruby 2.8.0
8
9
  - truffleruby
9
10
  before_install: gem install bundler -v 2.1.4
@@ -0,0 +1,2 @@
1
+ --no-private
2
+ --exclude lib/alba/version.rb
data/Gemfile CHANGED
@@ -5,10 +5,11 @@ gemspec
5
5
 
6
6
  gem 'activesupport', require: false # For backend
7
7
  gem 'coveralls', require: false # For test coverage
8
- gem 'minitest', '~> 5.0' # For test
8
+ gem 'minitest', '~> 5.14' # For test
9
9
  gem 'oj', '~> 3.10', platform: :ruby, require: false # For backend
10
10
  gem 'rake', '~> 13.0' # For test and automation
11
11
  gem 'rubocop', '>= 0.79.0', require: false # For lint
12
12
  gem 'rubocop-minitest', '~> 0.10.1', require: false # For lint
13
13
  gem 'rubocop-performance', '~> 1.7.1', require: false # For lint
14
14
  gem 'rubocop-sensible', '~> 0.3.0', require: false # For lint
15
+ gem 'yard', require: false
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- alba (0.11.0)
4
+ alba (0.11.1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -13,7 +13,6 @@ GEM
13
13
  tzinfo (~> 1.1)
14
14
  zeitwerk (~> 2.2, >= 2.2.2)
15
15
  ast (2.4.1)
16
- bigdecimal (2.0.0)
17
16
  concurrent-ruby (1.1.6)
18
17
  coveralls (0.8.23)
19
18
  json (>= 1.8, < 3)
@@ -25,9 +24,8 @@ GEM
25
24
  i18n (1.8.5)
26
25
  concurrent-ruby (~> 1.0)
27
26
  json (2.3.1)
28
- minitest (5.14.1)
29
- oj (3.10.12)
30
- bigdecimal (>= 1.0, < 3)
27
+ minitest (5.14.2)
28
+ oj (3.10.13)
31
29
  parallel (1.19.2)
32
30
  parser (2.7.1.4)
33
31
  ast (~> 2.4.1)
@@ -35,7 +33,7 @@ GEM
35
33
  rake (13.0.1)
36
34
  regexp_parser (1.7.1)
37
35
  rexml (3.2.4)
38
- rubocop (0.89.1)
36
+ rubocop (0.90.0)
39
37
  parallel (~> 1.10)
40
38
  parser (>= 2.7.1.1)
41
39
  rainbow (>= 2.2.2, < 4.0)
@@ -68,6 +66,7 @@ GEM
68
66
  tzinfo (1.2.7)
69
67
  thread_safe (~> 0.1)
70
68
  unicode-display_width (1.7.0)
69
+ yard (0.9.25)
71
70
  zeitwerk (2.4.0)
72
71
 
73
72
  PLATFORMS
@@ -77,13 +76,14 @@ DEPENDENCIES
77
76
  activesupport
78
77
  alba!
79
78
  coveralls
80
- minitest (~> 5.0)
79
+ minitest (~> 5.14)
81
80
  oj (~> 3.10)
82
81
  rake (~> 13.0)
83
82
  rubocop (>= 0.79.0)
84
83
  rubocop-minitest (~> 0.10.1)
85
84
  rubocop-performance (~> 1.7.1)
86
85
  rubocop-sensible (~> 0.3.0)
86
+ yard
87
87
 
88
88
  BUNDLED WITH
89
89
  2.1.4
data/README.md CHANGED
@@ -2,24 +2,26 @@
2
2
  [![Build Status](https://travis-ci.com/okuramasafumi/alba.svg?branch=master)](https://travis-ci.com/okuramasafumi/alba)
3
3
  [![Coverage Status](https://coveralls.io/repos/github/okuramasafumi/alba/badge.svg?branch=master)](https://coveralls.io/github/okuramasafumi/alba?branch=master)
4
4
  [![Maintainability](https://api.codeclimate.com/v1/badges/fdab4cc0de0b9addcfe8/maintainability)](https://codeclimate.com/github/okuramasafumi/alba/maintainability)
5
+ ![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/okuramasafumi/alba)
6
+ ![GitHub](https://img.shields.io/github/license/okuramasafumi/alba)
5
7
 
6
8
  # Alba
7
9
 
8
10
  `Alba` is the fastest JSON serializer for Ruby.
9
11
 
10
- # Why yet another JSON serializer?
12
+ ## Why yet another JSON serializer?
11
13
 
12
14
  We know that there are several other JSON serializers for Ruby around, but none of them made us satisfied.
13
15
 
14
16
  Alba has some advantages over other JSON serializers which we've wanted to have.
15
17
 
16
- ## Easy to understand
18
+ ### Easy to understand
17
19
 
18
20
  DSL is great. It makes the coding experience natural and intuitive. However, remembering lots of DSL requires us a lot of effort. Unfortunately, most of the existing libraries have implemented their features via DSL and it's not easy to understand how they behave entirely. Alba's core DSL are only four (`attributes`, `attribute`, `one` and `many`) so it's easy to understand how to use.
19
21
 
20
22
  Alba is also understandable internally. The codebase is much smaller than the alternatives. In fact, it's less than 300 lines of code. Look at the code on [GitHub](https://github.com/okuramasafumi/alba/tree/master/lib) and you'll be surprised how simple it is!
21
23
 
22
- ## Performance
24
+ ### Performance
23
25
 
24
26
  Alba is faster than most of the alternatives. We have a [benchmark](https://gist.github.com/okuramasafumi/4e375525bd3a28e4ca812d2a3b3e5829).
25
27
 
@@ -43,6 +45,32 @@ Or install it yourself as:
43
45
 
44
46
  Alba supports CRuby 2.5.7 and higher and latest TruffleRuby.
45
47
 
48
+ ## Documentation
49
+
50
+ You can find the documentation on [RubyDoc](https://rubydoc.info/gems/alba).
51
+
52
+ ## Features
53
+
54
+ * Resource-based serialization
55
+ * Arbitrary attribute definition
56
+ * One and many association with the ability to define them inline
57
+ * Adding condition and filter to association
58
+ * Parameters can be injected and used in attributes and associations
59
+ * Setting root key separately in Serializer
60
+ * Adding metadata
61
+ * Selectable backend
62
+ * No runtime dependencies
63
+
64
+ ## Anti features
65
+
66
+ * Sorting keys
67
+ * Class level support of parameters
68
+ * Supporting all existing JSON encoder/decoder
69
+ * Cache
70
+ * [JSON:API](https://jsonapi.org) support
71
+ * Association name inflection
72
+ * And many others
73
+
46
74
  ## Usage
47
75
 
48
76
  ### Configuration
@@ -129,7 +157,7 @@ class ArticleResource
129
157
  attributes :title
130
158
  end
131
159
 
132
- class UserResource1
160
+ class UserResource
133
161
  include Alba::Resource
134
162
 
135
163
  attributes :id
@@ -143,7 +171,7 @@ user.articles << article1
143
171
  article2 = Article.new(2, 'Super nice', 'Really nice!')
144
172
  user.articles << article2
145
173
 
146
- UserResource1.new(user).serialize
174
+ UserResource.new(user).serialize
147
175
  # => '{"id":1,"articles":[{"title":"Hello World!"},{"title":"Super nice"}]}'
148
176
  ```
149
177
 
@@ -1,21 +1,36 @@
1
- require 'alba/version'
2
- require 'alba/serializer'
3
- require 'alba/resource'
1
+ require_relative 'alba/version'
2
+ require_relative 'alba/serializer'
3
+ require_relative 'alba/resource'
4
4
 
5
5
  # Core module
6
6
  module Alba
7
+ # Base class for Errors
7
8
  class Error < StandardError; end
9
+ # Error class for backend which is not supported
8
10
  class UnsupportedBackend < Error; end
9
11
 
10
12
  class << self
11
13
  attr_reader :backend, :encoder
12
14
  attr_accessor :default_serializer
13
15
 
16
+ # Set the backend, which actually serializes object into JSON
17
+ #
18
+ # @param backend [#to_sym, nil] the name of the backend
19
+ # Possible values are `oj`, `active_support`, `default`, `json` and nil
20
+ # @return [Proc] the proc to encode object into JSON
21
+ # @raise [Alba::UnsupportedBackend] if backend is not supported
14
22
  def backend=(backend)
15
23
  @backend = backend&.to_sym
16
24
  set_encoder
17
25
  end
18
26
 
27
+ # Serialize the object with inline definitions
28
+ #
29
+ # @param object [Object] the object to be serialized
30
+ # @param with [nil, Proc, Alba::Serializer] selializer
31
+ # @param block [Block] resource block
32
+ # @return [String] serialized JSON string
33
+ # @raise [ArgumentError] if block is absent or `with` argument's type is wrong
19
34
  def serialize(object, with: nil, &block)
20
35
  raise ArgumentError, 'Block required' unless block
21
36
 
@@ -2,6 +2,10 @@ module Alba
2
2
  # Base class for `One` and `Many`
3
3
  # Child class should implement `to_hash` method
4
4
  class Association
5
+ # @param name [Symbol] name of the method to fetch association
6
+ # @param condition [Proc] a proc filtering data
7
+ # @param resource [Class<Alba::Resource>] a resource class for the association
8
+ # @param block [Block] used to define resource when resource arg is absent
5
9
  def initialize(name:, condition: nil, resource: nil, &block)
6
10
  @name = name
7
11
  @condition = condition
@@ -10,6 +14,7 @@ module Alba
10
14
  raise ArgumentError, 'resource or block is required' if @resource.nil? && @block.nil?
11
15
  end
12
16
 
17
+ # @abstract
13
18
  def to_hash
14
19
  :not_implemented
15
20
  end
@@ -1,8 +1,13 @@
1
- require 'alba/association'
1
+ require_relative 'association'
2
2
 
3
3
  module Alba
4
4
  # Representing many association
5
5
  class Many < Association
6
+ # Recursively converts objects into an Array of Hashes
7
+ #
8
+ # @param target [Object] the object having an association method
9
+ # @param params [Hash] user-given Hash for arbitrary data
10
+ # @return [Array<Hash>]
6
11
  def to_hash(target, params: {})
7
12
  objects = target.public_send(@name)
8
13
  objects = @condition.call(objects, params) if @condition
@@ -1,8 +1,13 @@
1
- require 'alba/association'
1
+ require_relative 'association'
2
2
 
3
3
  module Alba
4
4
  # Representing one association
5
5
  class One < Association
6
+ # Recursively converts an object into a Hash
7
+ #
8
+ # @param target [Object] the object having an association method
9
+ # @param params [Hash] user-given Hash for arbitrary data
10
+ # @return [Hash]
6
11
  def to_hash(target, params: {})
7
12
  object = target.public_send(@name)
8
13
  object = @condition.call(object, params) if @condition
@@ -1,11 +1,16 @@
1
- require 'alba/serializer'
2
- require 'alba/one'
3
- require 'alba/many'
1
+ require_relative 'serializer'
2
+ require_relative 'one'
3
+ require_relative 'many'
4
4
 
5
5
  module Alba
6
6
  # This module represents what should be serialized
7
7
  module Resource
8
+ # @!parse include InstanceMethods
9
+ # @!parse extend ClassMethods
8
10
  DSLS = {_attributes: {}, _serializer: nil, _key: nil}.freeze
11
+ private_constant :DSLS
12
+
13
+ # @private
9
14
  def self.included(base)
10
15
  super
11
16
  base.class_eval do
@@ -22,12 +27,18 @@ module Alba
22
27
  module InstanceMethods
23
28
  attr_reader :object, :_key, :params
24
29
 
30
+ # @param object [Object] the object to be serialized
31
+ # @param params [Hash] user-given Hash for arbitrary data
25
32
  def initialize(object, params: {})
26
33
  @object = object
27
- @params = params
34
+ @params = params.freeze
28
35
  DSLS.each_key { |name| instance_variable_set("@#{name}", self.class.public_send(name)) }
29
36
  end
30
37
 
38
+ # Get serializer with `with` argument and serialize self with it
39
+ #
40
+ # @param with [nil, Proc, Alba::Serializer] selializer
41
+ # @return [String] serialized JSON string
31
42
  def serialize(with: nil)
32
43
  serializer = case with
33
44
  when nil
@@ -42,11 +53,15 @@ module Alba
42
53
  serializer.new(self).serialize
43
54
  end
44
55
 
56
+ # A Hash for serialization
57
+ #
58
+ # @return [Hash]
45
59
  def serializable_hash
46
60
  collection? ? @object.map(&converter) : converter.call(@object)
47
61
  end
48
62
  alias to_hash serializable_hash
49
63
 
64
+ # @return [Symbol]
50
65
  def key
51
66
  @_key || self.class.name.delete_suffix('Resource').downcase.gsub(/:{2}/, '_').to_sym
52
67
  end
@@ -91,38 +106,72 @@ module Alba
91
106
  module ClassMethods
92
107
  attr_reader(*DSLS.keys)
93
108
 
109
+ # @private
94
110
  def inherited(subclass)
95
111
  super
96
112
  DSLS.each_key { |name| subclass.instance_variable_set("@#{name}", instance_variable_get("@#{name}").clone) }
97
113
  end
98
114
 
115
+ # Set multiple attributes at once
116
+ #
117
+ # @param attrs [Array<String, Symbol>]
99
118
  def attributes(*attrs)
100
119
  attrs.each { |attr_name| @_attributes[attr_name.to_sym] = attr_name.to_sym }
101
120
  end
102
121
 
122
+ # Set an attribute with the given block
123
+ #
124
+ # @param name [String, Symbol] key name
125
+ # @param block [Block] the block called during serialization
126
+ # @raise [ArgumentError] if block is absent
103
127
  def attribute(name, &block)
104
128
  raise ArgumentError, 'No block given in attribute method' unless block
105
129
 
106
130
  @_attributes[name.to_sym] = block
107
131
  end
108
132
 
133
+ # Set One association
134
+ #
135
+ # @param name [String, Symbol]
136
+ # @param condition [Proc]
137
+ # @param resource [Class<Alba::Resource>]
138
+ # @param key [String, Symbol] used as key when given
139
+ # @param block [Block]
140
+ # @see Alba::One#initialize
109
141
  def one(name, condition = nil, resource: nil, key: nil, &block)
110
142
  @_attributes[key&.to_sym || name.to_sym] = One.new(name: name, condition: condition, resource: resource, &block)
111
143
  end
112
144
 
145
+ # Set Many association
146
+ #
147
+ # @param name [String, Symbol]
148
+ # @param condition [Proc]
149
+ # @param resource [Class<Alba::Resource>]
150
+ # @param key [String, Symbol] used as key when given
151
+ # @param block [Block]
152
+ # @see Alba::Many#initialize
113
153
  def many(name, condition = nil, resource: nil, key: nil, &block)
114
154
  @_attributes[key&.to_sym || name.to_sym] = Many.new(name: name, condition: condition, resource: resource, &block)
115
155
  end
116
156
 
157
+ # Set serializer for the resource
158
+ #
159
+ # @param name [Alba::Serializer]
117
160
  def serializer(name)
118
161
  @_serializer = name <= Alba::Serializer ? name : nil
119
162
  end
120
163
 
164
+ # Set key
165
+ #
166
+ # @param key [String, Symbol]
121
167
  def key(key)
122
168
  @_key = key.to_sym
123
169
  end
124
170
 
171
+ # Delete attributes
125
172
  # Use this DSL in child class to ignore certain attributes
173
+ #
174
+ # @param attributes [Array<String, Symbol>]
126
175
  def ignoring(*attributes)
127
176
  attributes.each do |attr_name|
128
177
  @_attributes.delete(attr_name.to_sym)
@@ -1,6 +1,10 @@
1
1
  module Alba
2
2
  # This module represents how a resource should be serialized.
3
3
  module Serializer
4
+ # @!parse include InstanceMethods
5
+ # @!parse extend ClassMethods
6
+
7
+ # @private
4
8
  def self.included(base)
5
9
  super
6
10
  base.class_eval do
@@ -13,6 +17,7 @@ module Alba
13
17
 
14
18
  # Instance methods
15
19
  module InstanceMethods
20
+ # @param resource [Alba::Resource]
16
21
  def initialize(resource)
17
22
  @resource = resource
18
23
  @hash = resource.serializable_hash
@@ -21,6 +26,9 @@ module Alba
21
26
  @hash.is_a?(Hash) ? @hash.merge!(metadata.to_h) : @hash << metadata
22
27
  end
23
28
 
29
+ # Use real encoder to actually serialize to JSON
30
+ #
31
+ # @return [String] JSON string
24
32
  def serialize
25
33
  Alba.encoder.call(@hash)
26
34
  end
@@ -42,17 +50,25 @@ module Alba
42
50
  module ClassMethods
43
51
  attr_reader :_opts, :_metadata
44
52
 
53
+ # @private
45
54
  def inherited(subclass)
46
55
  super
47
56
  %w[_opts _metadata].each { |name| subclass.instance_variable_set("@#{name}", public_send(name).clone) }
48
57
  end
49
58
 
59
+ # Set options, currently key only
60
+ #
61
+ # @param key [Boolean, Symbol]
50
62
  def set(key: false)
51
63
  @_opts[:key] = key
52
64
  end
53
65
 
66
+ # Set metadata
67
+ #
68
+ # @param name [String, Symbol] key for the metadata
69
+ # @param block [Block] the content of the metadata
54
70
  def metadata(name, &block)
55
- @_metadata[name] = block
71
+ @_metadata[name.to_sym] = block
56
72
  end
57
73
  end
58
74
  end
@@ -1,3 +1,3 @@
1
1
  module Alba
2
- VERSION = '0.11.0'.freeze
2
+ VERSION = '0.11.1'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: alba
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.0
4
+ version: 0.11.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - OKURA Masafumi
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-08-26 00:00:00.000000000 Z
11
+ date: 2020-09-02 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Alba is designed to be a simple, easy to use and fast alternative to
14
14
  existing JSON serializers. Its performance is better than almost all gems which
@@ -22,6 +22,7 @@ files:
22
22
  - ".gitignore"
23
23
  - ".rubocop.yml"
24
24
  - ".travis.yml"
25
+ - ".yardopts"
25
26
  - CODE_OF_CONDUCT.md
26
27
  - Gemfile
27
28
  - Gemfile.lock