alba 0.13.1 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,64 @@
1
+ module Alba
2
+ # Representing typed attributes to encapsulate logic about types
3
+ class TypedAttribute
4
+ # @param name [Symbol, String]
5
+ # @param type [Symbol, Class]
6
+ # @param converter [Proc]
7
+ def initialize(name:, type:, converter:)
8
+ @name = name
9
+ @type = type
10
+ @converter = case converter
11
+ when true then default_converter
12
+ when false, nil then null_converter
13
+ else converter
14
+ end
15
+ end
16
+
17
+ # @param object [Object] target to check and convert type with
18
+ # @return [String, Integer, Boolean] type-checked or type-converted object
19
+ def value(object)
20
+ value, result = check(object)
21
+ result ? value : @converter.call(value)
22
+ rescue TypeError
23
+ raise TypeError, "Attribute #{@name} is expected to be #{@type} but actually #{display_value_for(value)}."
24
+ end
25
+
26
+ private
27
+
28
+ def check(object)
29
+ value = object.public_send(@name)
30
+ type_correct = case @type
31
+ when :String, ->(klass) { klass == String }
32
+ value.is_a?(String)
33
+ when :Integer, ->(klass) { klass == Integer }
34
+ value.is_a?(Integer)
35
+ when :Boolean
36
+ [true, false].include?(value)
37
+ else
38
+ raise Alba::UnsupportedType, "Unknown type: #{@type}"
39
+ end
40
+ [value, type_correct]
41
+ end
42
+
43
+ def default_converter
44
+ case @type
45
+ when :String, ->(klass) { klass == String }
46
+ ->(object) { object.to_s }
47
+ when :Integer, ->(klass) { klass == Integer }
48
+ ->(object) { Integer(object) }
49
+ when :Boolean
50
+ ->(object) { !!object }
51
+ else
52
+ raise Alba::UnsupportedType, "Unknown type: #{@type}"
53
+ end
54
+ end
55
+
56
+ def null_converter
57
+ ->(_) { raise TypeError }
58
+ end
59
+
60
+ def display_value_for(value)
61
+ value.nil? ? 'nil' : value.class.name
62
+ end
63
+ end
64
+ end
data/lib/alba/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Alba
2
- VERSION = '0.13.1'.freeze
2
+ VERSION = '1.3.0'.freeze
3
3
  end
data/sider.yml CHANGED
@@ -49,10 +49,8 @@ linter:
49
49
  # norc: true
50
50
 
51
51
  # # https://help.sider.review/getting-started/custom-configuration#ignore
52
- # ignore:
53
- # - "*.pdf"
54
- # - "*.mp4"
55
- # - "images/**"
52
+ ignore:
53
+ - 'test/**/*'
56
54
 
57
55
  # # https://help.sider.review/getting-started/custom-configuration#branchesexclude
58
56
  # branches:
metadata CHANGED
@@ -1,45 +1,54 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: alba
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.13.1
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - OKURA Masafumi
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-03-24 00:00:00.000000000 Z
11
+ date: 2021-05-31 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: Alba is designed to be a simple, easy to use and fast alternative to
14
- existing JSON serializers. Its performance is better than almost all gems which
15
- do similar things. The internal is so simple that it's easy to hack and maintain.
13
+ description: Alba is the fastest JSON serializer for Ruby. It focuses on performance,
14
+ flexibility and usability.
16
15
  email:
17
16
  - masafumi.o1988@gmail.com
18
17
  executables: []
19
18
  extensions: []
20
19
  extra_rdoc_files: []
21
20
  files:
21
+ - ".github/ISSUE_TEMPLATE/bug_report.md"
22
+ - ".github/ISSUE_TEMPLATE/feature_request.md"
23
+ - ".github/dependabot.yml"
22
24
  - ".github/workflows/main.yml"
23
25
  - ".gitignore"
24
26
  - ".rubocop.yml"
25
27
  - ".yardopts"
28
+ - CHANGELOG.md
26
29
  - CODE_OF_CONDUCT.md
27
30
  - Gemfile
28
- - Gemfile.lock
29
31
  - LICENSE.txt
30
32
  - README.md
31
33
  - Rakefile
34
+ - SECURITY.md
32
35
  - alba.gemspec
33
- - benchmark/local.rb
36
+ - benchmark/collection.rb
37
+ - benchmark/single_resource.rb
34
38
  - bin/console
35
39
  - bin/setup
40
+ - codecov.yml
41
+ - gemfiles/all.gemfile
42
+ - gemfiles/without_active_support.gemfile
43
+ - gemfiles/without_oj.gemfile
36
44
  - lib/alba.rb
37
45
  - lib/alba/association.rb
38
- - lib/alba/key_transformer.rb
46
+ - lib/alba/default_inflector.rb
47
+ - lib/alba/key_transform_factory.rb
39
48
  - lib/alba/many.rb
40
49
  - lib/alba/one.rb
41
50
  - lib/alba/resource.rb
42
- - lib/alba/serializer.rb
51
+ - lib/alba/typed_attribute.rb
43
52
  - lib/alba/version.rb
44
53
  - sider.yml
45
54
  homepage: https://github.com/okuramasafumi/alba
@@ -48,7 +57,7 @@ licenses:
48
57
  metadata:
49
58
  homepage_uri: https://github.com/okuramasafumi/alba
50
59
  source_code_uri: https://github.com/okuramasafumi/alba
51
- changelog_uri: https://github.com/okuramasafumi/alba/CHANGELOG.md
60
+ changelog_uri: https://github.com/okuramasafumi/alba/blob/master/CHANGELOG.md
52
61
  post_install_message:
53
62
  rdoc_options: []
54
63
  require_paths:
@@ -57,14 +66,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
57
66
  requirements:
58
67
  - - ">="
59
68
  - !ruby/object:Gem::Version
60
- version: 2.5.7
69
+ version: 2.5.0
61
70
  required_rubygems_version: !ruby/object:Gem::Requirement
62
71
  requirements:
63
72
  - - ">="
64
73
  - !ruby/object:Gem::Version
65
74
  version: '0'
66
75
  requirements: []
67
- rubygems_version: 3.2.11
76
+ rubygems_version: 3.2.16
68
77
  signing_key:
69
78
  specification_version: 4
70
79
  summary: Alba is the fastest JSON serializer for Ruby.
data/Gemfile.lock DELETED
@@ -1,92 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- alba (0.13.1)
5
-
6
- GEM
7
- remote: https://rubygems.org/
8
- specs:
9
- activesupport (6.1.3)
10
- concurrent-ruby (~> 1.0, >= 1.0.2)
11
- i18n (>= 1.6, < 2)
12
- minitest (>= 5.1)
13
- tzinfo (~> 2.0)
14
- zeitwerk (~> 2.3)
15
- ast (2.4.2)
16
- concurrent-ruby (1.1.8)
17
- coveralls (0.8.23)
18
- json (>= 1.8, < 3)
19
- simplecov (~> 0.16.1)
20
- term-ansicolor (~> 1.3)
21
- thor (>= 0.19.4, < 2.0)
22
- tins (~> 1.6)
23
- docile (1.3.2)
24
- i18n (1.8.9)
25
- concurrent-ruby (~> 1.0)
26
- json (2.3.1)
27
- minitest (5.14.3)
28
- oj (3.11.2)
29
- parallel (1.20.1)
30
- parser (3.0.0.0)
31
- ast (~> 2.4.1)
32
- rainbow (3.0.0)
33
- rake (13.0.3)
34
- regexp_parser (2.1.1)
35
- rexml (3.2.4)
36
- rubocop (1.11.0)
37
- parallel (~> 1.10)
38
- parser (>= 3.0.0.0)
39
- rainbow (>= 2.2.2, < 4.0)
40
- regexp_parser (>= 1.8, < 3.0)
41
- rexml
42
- rubocop-ast (>= 1.2.0, < 2.0)
43
- ruby-progressbar (~> 1.7)
44
- unicode-display_width (>= 1.4.0, < 3.0)
45
- rubocop-ast (1.4.1)
46
- parser (>= 2.7.1.5)
47
- rubocop-minitest (0.10.3)
48
- rubocop (>= 0.87, < 2.0)
49
- rubocop-performance (1.10.1)
50
- rubocop (>= 0.90.0, < 2.0)
51
- rubocop-ast (>= 0.4.0)
52
- rubocop-rake (0.5.1)
53
- rubocop
54
- rubocop-sensible (0.3.0)
55
- rubocop (>= 0.60.0)
56
- ruby-progressbar (1.11.0)
57
- simplecov (0.16.1)
58
- docile (~> 1.1)
59
- json (>= 1.8, < 3)
60
- simplecov-html (~> 0.10.0)
61
- simplecov-html (0.10.2)
62
- sync (0.5.0)
63
- term-ansicolor (1.7.1)
64
- tins (~> 1.0)
65
- thor (1.0.1)
66
- tins (1.25.0)
67
- sync
68
- tzinfo (2.0.4)
69
- concurrent-ruby (~> 1.0)
70
- unicode-display_width (2.0.0)
71
- yard (0.9.26)
72
- zeitwerk (2.4.2)
73
-
74
- PLATFORMS
75
- ruby
76
-
77
- DEPENDENCIES
78
- activesupport
79
- alba!
80
- coveralls
81
- minitest (~> 5.14)
82
- oj (~> 3.11)
83
- rake (~> 13.0)
84
- rubocop (>= 0.79.0)
85
- rubocop-minitest (~> 0.10.3)
86
- rubocop-performance (~> 1.10.1)
87
- rubocop-rake (>= 0.5.1)
88
- rubocop-sensible (~> 0.3.0)
89
- yard
90
-
91
- BUNDLED WITH
92
- 2.2.6
data/benchmark/local.rb DELETED
@@ -1,198 +0,0 @@
1
- # Benchmark script to run varieties of JSON serializers
2
- # Fetch Alba from local, otherwise fetch latest from RubyGems
3
-
4
- require "bundler/inline"
5
-
6
- gemfile(true) do
7
- source "https://rubygems.org"
8
-
9
- git_source(:github) { |repo| "https://github.com/#{repo}.git" }
10
-
11
- gem "activerecord", "6.1.3"
12
- gem "sqlite3"
13
- gem "jbuilder"
14
- gem "active_model_serializers"
15
- gem "blueprinter"
16
- gem "representable"
17
- gem "alba", path: '../'
18
- gem "oj"
19
- gem "multi_json"
20
- end
21
-
22
- require "active_record"
23
- require "sqlite3"
24
- require "logger"
25
- require "oj"
26
- Oj.optimize_rails
27
-
28
- ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
29
- # ActiveRecord::Base.logger = Logger.new(STDOUT)
30
-
31
- ActiveRecord::Schema.define do
32
- create_table :posts, force: true do |t|
33
- t.string :body
34
- end
35
-
36
- create_table :comments, force: true do |t|
37
- t.integer :post_id
38
- t.string :body
39
- t.integer :commenter_id
40
- end
41
-
42
- create_table :users, force: true do |t|
43
- t.string :name
44
- end
45
- end
46
-
47
- class Post < ActiveRecord::Base
48
- has_many :comments
49
- has_many :commenters, through: :comments, class_name: 'User', source: :commenter
50
-
51
- def attributes
52
- {id: nil, body: nil, commenter_names: commenter_names}
53
- end
54
-
55
- def commenter_names
56
- commenters.pluck(:name)
57
- end
58
- end
59
-
60
- class Comment < ActiveRecord::Base
61
- belongs_to :post
62
- belongs_to :commenter, class_name: 'User'
63
-
64
- def attributes
65
- {id: nil, body: nil}
66
- end
67
- end
68
-
69
- class User < ActiveRecord::Base
70
- has_many :comments
71
- end
72
-
73
- require "alba"
74
- Alba.backend = :oj
75
-
76
- class AlbaCommentResource
77
- include ::Alba::Resource
78
- attributes :id, :body
79
- end
80
-
81
- class AlbaPostResource
82
- include ::Alba::Resource
83
- attributes :id, :body
84
- many :comments, resource: AlbaCommentResource
85
- attribute :commenter_names do |post|
86
- post.commenters.pluck(:name)
87
- end
88
- end
89
-
90
- require "jbuilder"
91
- class Post
92
- def to_builder
93
- Jbuilder.new do |post|
94
- post.call(self, :id, :body, :comments, :commenter_names)
95
- end
96
- end
97
-
98
- def commenter_names
99
- commenters.pluck(:name)
100
- end
101
- end
102
-
103
- class Comment
104
- def to_builder
105
- Jbuilder.new do |comment|
106
- comment.call(self, :id, :body)
107
- end
108
- end
109
- end
110
-
111
- require "active_model_serializers"
112
-
113
- class AMSCommentSerializer < ActiveModel::Serializer
114
- attributes :id, :body
115
- end
116
-
117
- class AMSPostSerializer < ActiveModel::Serializer
118
- attributes :id, :body
119
- has_many :comments, serializer: AMSCommentSerializer
120
- attribute :commenter_names
121
- def commenter_names
122
- object.commenters.pluck(:name)
123
- end
124
- end
125
-
126
- require "blueprinter"
127
-
128
- class CommentBlueprint < Blueprinter::Base
129
- fields :id, :body
130
- end
131
-
132
- class PostBlueprint < Blueprinter::Base
133
- fields :id, :body, :commenter_names
134
- association :comments, blueprint: CommentBlueprint
135
- def commenter_names
136
- commenters.pluck(:name)
137
- end
138
- end
139
-
140
- require "representable"
141
-
142
- class CommentRepresenter < Representable::Decorator
143
- include Representable::JSON
144
-
145
- property :id
146
- property :body
147
- end
148
-
149
- class PostRepresenter < Representable::Decorator
150
- include Representable::JSON
151
-
152
- property :id
153
- property :body
154
- property :commenter_names
155
- collection :comments
156
-
157
- def commenter_names
158
- commenters.pluck(:name)
159
- end
160
- end
161
-
162
- post = Post.create!(body: 'post')
163
- user1 = User.create!(name: 'John')
164
- user2 = User.create!(name: 'Jane')
165
- post.comments.create!(commenter: user1, body: 'Comment1')
166
- post.comments.create!(commenter: user2, body: 'Comment2')
167
- post.reload
168
-
169
- alba = Proc.new { AlbaPostResource.new(post).serialize }
170
- jbuilder = Proc.new { post.to_builder.target! }
171
- ams = Proc.new { AMSPostSerializer.new(post, {}).to_json }
172
- rails = Proc.new { ActiveSupport::JSON.encode(post.serializable_hash(include: :comments)) }
173
- blueprinter = Proc.new { PostBlueprint.render(post) }
174
- representable = Proc.new { PostRepresenter.new(post).to_json }
175
- alba_inline = Proc.new do
176
- Alba.serialize(post) do
177
- attributes :id, :body
178
- attribute :commenter_names do |post|
179
- post.commenters.pluck(:name)
180
- end
181
- many :comments do
182
- attributes :id, :body
183
- end
184
- end
185
- end
186
- [alba, jbuilder, ams, rails, blueprinter, representable, alba_inline].each {|x| puts x.call }
187
-
188
- require 'benchmark'
189
- time = 1000
190
- Benchmark.bmbm do |x|
191
- x.report(:alba) { time.times(&alba) }
192
- x.report(:jbuilder) { time.times(&jbuilder) }
193
- x.report(:ams) { time.times(&ams) }
194
- x.report(:rails) { time.times(&rails) }
195
- x.report(:blueprinter) { time.times(&blueprinter) }
196
- x.report(:representable) { time.times(&representable) }
197
- x.report(:alba_inline) { time.times(&alba_inline) }
198
- end