alba 0.11.1 → 1.0.1
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/main.yml +34 -0
- data/.gitignore +2 -0
- data/.rubocop.yml +21 -0
- data/CHANGELOG.md +20 -0
- data/Gemfile +10 -4
- data/README.md +262 -34
- data/Rakefile +4 -1
- data/alba.gemspec +2 -2
- data/benchmark/local.rb +198 -0
- data/gemfiles/all.gemfile +18 -0
- data/gemfiles/without_active_support.gemfile +17 -0
- data/gemfiles/without_oj.gemfile +17 -0
- data/lib/alba.rb +38 -16
- data/lib/alba/association.rb +22 -7
- data/lib/alba/key_transformer.rb +32 -0
- data/lib/alba/many.rb +6 -3
- data/lib/alba/one.rb +5 -2
- data/lib/alba/resource.rb +125 -56
- data/lib/alba/version.rb +1 -1
- data/sider.yml +1 -0
- metadata +12 -8
- data/.travis.yml +0 -10
- data/Gemfile.lock +0 -89
- data/lib/alba/serializer.rb +0 -75
data/lib/alba/many.rb
CHANGED
@@ -9,9 +9,12 @@ module Alba
|
|
9
9
|
# @param params [Hash] user-given Hash for arbitrary data
|
10
10
|
# @return [Array<Hash>]
|
11
11
|
def to_hash(target, params: {})
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
@object = target.public_send(@name)
|
13
|
+
@object = @condition.call(@object, params) if @condition
|
14
|
+
return if @object.nil?
|
15
|
+
|
16
|
+
@resource = constantize(@resource)
|
17
|
+
@object.map { |o| @resource.new(o, params: params).to_hash }
|
15
18
|
end
|
16
19
|
end
|
17
20
|
end
|
data/lib/alba/one.rb
CHANGED
@@ -9,8 +9,11 @@ module Alba
|
|
9
9
|
# @param params [Hash] user-given Hash for arbitrary data
|
10
10
|
# @return [Hash]
|
11
11
|
def to_hash(target, params: {})
|
12
|
-
object = target.public_send(@name)
|
13
|
-
object = @condition.call(object, params) if @condition
|
12
|
+
@object = target.public_send(@name)
|
13
|
+
@object = @condition.call(object, params) if @condition
|
14
|
+
return if @object.nil?
|
15
|
+
|
16
|
+
@resource = constantize(@resource)
|
14
17
|
@resource.new(object, params: params).to_hash
|
15
18
|
end
|
16
19
|
end
|
data/lib/alba/resource.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require_relative 'serializer'
|
2
1
|
require_relative 'one'
|
3
2
|
require_relative 'many'
|
4
3
|
|
@@ -7,7 +6,7 @@ module Alba
|
|
7
6
|
module Resource
|
8
7
|
# @!parse include InstanceMethods
|
9
8
|
# @!parse extend ClassMethods
|
10
|
-
DSLS = {_attributes: {},
|
9
|
+
DSLS = {_attributes: {}, _key: nil, _transform_keys: nil, _on_error: nil}.freeze
|
11
10
|
private_constant :DSLS
|
12
11
|
|
13
12
|
# @private
|
@@ -25,7 +24,7 @@ module Alba
|
|
25
24
|
|
26
25
|
# Instance methods
|
27
26
|
module InstanceMethods
|
28
|
-
attr_reader :object, :
|
27
|
+
attr_reader :object, :params
|
29
28
|
|
30
29
|
# @param object [Object] the object to be serialized
|
31
30
|
# @param params [Hash] user-given Hash for arbitrary data
|
@@ -35,22 +34,14 @@ module Alba
|
|
35
34
|
DSLS.each_key { |name| instance_variable_set("@#{name}", self.class.public_send(name)) }
|
36
35
|
end
|
37
36
|
|
38
|
-
#
|
37
|
+
# Serialize object into JSON string
|
39
38
|
#
|
40
|
-
# @param
|
39
|
+
# @param key [Symbol]
|
41
40
|
# @return [String] serialized JSON string
|
42
|
-
def serialize(
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
when ->(obj) { obj.is_a?(Class) && obj <= Alba::Serializer }
|
47
|
-
with
|
48
|
-
when Proc
|
49
|
-
inline_extended_serializer(with)
|
50
|
-
else
|
51
|
-
raise ArgumentError, 'Unexpected type for with, possible types are Class or Proc'
|
52
|
-
end
|
53
|
-
serializer.new(self).serialize
|
41
|
+
def serialize(key: nil)
|
42
|
+
key = key.nil? ? _key : key
|
43
|
+
hash = key && key != '' ? {key.to_s => serializable_hash} : serializable_hash
|
44
|
+
Alba.encoder.call(hash)
|
54
45
|
end
|
55
46
|
|
56
47
|
# A Hash for serialization
|
@@ -61,40 +52,88 @@ module Alba
|
|
61
52
|
end
|
62
53
|
alias to_hash serializable_hash
|
63
54
|
|
64
|
-
# @return [Symbol]
|
65
|
-
def key
|
66
|
-
@_key || self.class.name.delete_suffix('Resource').downcase.gsub(/:{2}/, '_').to_sym
|
67
|
-
end
|
68
|
-
|
69
55
|
private
|
70
56
|
|
57
|
+
# @return [String]
|
58
|
+
def _key
|
59
|
+
if @_key == true && Alba.inferring
|
60
|
+
demodulized = ActiveSupport::Inflector.demodulize(self.class.name)
|
61
|
+
meth = collection? ? :tableize : :singularize
|
62
|
+
ActiveSupport::Inflector.public_send(meth, demodulized.delete_suffix('Resource').downcase)
|
63
|
+
else
|
64
|
+
@_key.to_s
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
71
68
|
def converter
|
72
|
-
lambda do |
|
73
|
-
@_attributes.
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
when Proc
|
78
|
-
instance_exec(resource, &attribute)
|
79
|
-
when Alba::One, Alba::Many
|
80
|
-
attribute.to_hash(resource, params: params)
|
69
|
+
lambda do |object|
|
70
|
+
arrays = @_attributes.map do |key, attribute|
|
71
|
+
key = transform_key(key)
|
72
|
+
if attribute.is_a?(Array) # Conditional
|
73
|
+
conditional_attribute(object, key, attribute)
|
81
74
|
else
|
82
|
-
|
75
|
+
[key, fetch_attribute(object, attribute)]
|
83
76
|
end
|
77
|
+
rescue ::Alba::Error, FrozenError
|
78
|
+
raise
|
79
|
+
rescue StandardError => e
|
80
|
+
handle_error(e, object, key, attribute)
|
84
81
|
end
|
82
|
+
arrays.reject(&:empty?).to_h
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def conditional_attribute(object, key, attribute)
|
87
|
+
condition = attribute.last
|
88
|
+
arity = condition.arity
|
89
|
+
return [] if arity <= 1 && !condition.call(object)
|
90
|
+
|
91
|
+
fetched_attribute = fetch_attribute(object, attribute.first)
|
92
|
+
attr = if attribute.first.is_a?(Alba::Association)
|
93
|
+
attribute.first.object
|
94
|
+
else
|
95
|
+
fetched_attribute
|
96
|
+
end
|
97
|
+
return [] if arity >= 2 && !condition.call(object, attr)
|
98
|
+
|
99
|
+
[key, fetched_attribute]
|
100
|
+
end
|
101
|
+
|
102
|
+
def handle_error(error, object, key, attribute)
|
103
|
+
on_error = @_on_error || Alba._on_error
|
104
|
+
case on_error
|
105
|
+
when :raise, nil
|
106
|
+
raise
|
107
|
+
when :nullify
|
108
|
+
[key, nil]
|
109
|
+
when :ignore
|
110
|
+
[]
|
111
|
+
when Proc
|
112
|
+
on_error.call(error, object, key, attribute, self.class)
|
113
|
+
else
|
114
|
+
raise ::Alba::Error, "Unknown on_error: #{on_error.inspect}"
|
85
115
|
end
|
86
116
|
end
|
87
117
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
118
|
+
# Override this method to supply custom key transform method
|
119
|
+
def transform_key(key)
|
120
|
+
return key unless @_transform_keys
|
121
|
+
|
122
|
+
require_relative 'key_transformer'
|
123
|
+
KeyTransformer.transform(key, @_transform_keys)
|
92
124
|
end
|
93
125
|
|
94
|
-
def
|
95
|
-
|
96
|
-
|
97
|
-
|
126
|
+
def fetch_attribute(object, attribute)
|
127
|
+
case attribute
|
128
|
+
when Symbol
|
129
|
+
object.public_send attribute
|
130
|
+
when Proc
|
131
|
+
instance_exec(object, &attribute)
|
132
|
+
when Alba::One, Alba::Many
|
133
|
+
attribute.to_hash(object, params: params)
|
134
|
+
else
|
135
|
+
raise ::Alba::Error, "Unsupported type of attribute: #{attribute.class}"
|
136
|
+
end
|
98
137
|
end
|
99
138
|
|
100
139
|
def collection?
|
@@ -115,19 +154,24 @@ module Alba
|
|
115
154
|
# Set multiple attributes at once
|
116
155
|
#
|
117
156
|
# @param attrs [Array<String, Symbol>]
|
118
|
-
|
119
|
-
|
157
|
+
# @param options [Hash] option hash including `if` that is a condition to render these attributes
|
158
|
+
def attributes(*attrs, **options)
|
159
|
+
attrs.each do |attr_name|
|
160
|
+
attr = options[:if] ? [attr_name.to_sym, options[:if]] : attr_name.to_sym
|
161
|
+
@_attributes[attr_name.to_sym] = attr
|
162
|
+
end
|
120
163
|
end
|
121
164
|
|
122
165
|
# Set an attribute with the given block
|
123
166
|
#
|
124
167
|
# @param name [String, Symbol] key name
|
168
|
+
# @param options [Hash] option hash including `if` that is a condition to render
|
125
169
|
# @param block [Block] the block called during serialization
|
126
170
|
# @raise [ArgumentError] if block is absent
|
127
|
-
def attribute(name, &block)
|
171
|
+
def attribute(name, **options, &block)
|
128
172
|
raise ArgumentError, 'No block given in attribute method' unless block
|
129
173
|
|
130
|
-
@_attributes[name.to_sym] = block
|
174
|
+
@_attributes[name.to_sym] = options[:if] ? [block, options[:if]] : block
|
131
175
|
end
|
132
176
|
|
133
177
|
# Set One association
|
@@ -136,11 +180,15 @@ module Alba
|
|
136
180
|
# @param condition [Proc]
|
137
181
|
# @param resource [Class<Alba::Resource>]
|
138
182
|
# @param key [String, Symbol] used as key when given
|
183
|
+
# @param options [Hash] option hash including `if` that is a condition to render
|
139
184
|
# @param block [Block]
|
140
185
|
# @see Alba::One#initialize
|
141
|
-
def one(name, condition = nil, resource: nil, key: nil, &block)
|
142
|
-
|
186
|
+
def one(name, condition = nil, resource: nil, key: nil, **options, &block)
|
187
|
+
nesting = self.name&.rpartition('::')&.first
|
188
|
+
one = One.new(name: name, condition: condition, resource: resource, nesting: nesting, &block)
|
189
|
+
@_attributes[key&.to_sym || name.to_sym] = options[:if] ? [one, options[:if]] : one
|
143
190
|
end
|
191
|
+
alias has_one one
|
144
192
|
|
145
193
|
# Set Many association
|
146
194
|
#
|
@@ -148,24 +196,27 @@ module Alba
|
|
148
196
|
# @param condition [Proc]
|
149
197
|
# @param resource [Class<Alba::Resource>]
|
150
198
|
# @param key [String, Symbol] used as key when given
|
199
|
+
# @param options [Hash] option hash including `if` that is a condition to render
|
151
200
|
# @param block [Block]
|
152
201
|
# @see Alba::Many#initialize
|
153
|
-
def many(name, condition = nil, resource: nil, key: nil, &block)
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
# Set serializer for the resource
|
158
|
-
#
|
159
|
-
# @param name [Alba::Serializer]
|
160
|
-
def serializer(name)
|
161
|
-
@_serializer = name <= Alba::Serializer ? name : nil
|
202
|
+
def many(name, condition = nil, resource: nil, key: nil, **options, &block)
|
203
|
+
nesting = self.name&.rpartition('::')&.first
|
204
|
+
many = Many.new(name: name, condition: condition, resource: resource, nesting: nesting, &block)
|
205
|
+
@_attributes[key&.to_sym || name.to_sym] = options[:if] ? [many, options[:if]] : many
|
162
206
|
end
|
207
|
+
alias has_many many
|
163
208
|
|
164
209
|
# Set key
|
165
210
|
#
|
166
211
|
# @param key [String, Symbol]
|
167
212
|
def key(key)
|
168
|
-
@_key = key.to_sym
|
213
|
+
@_key = key.respond_to?(:to_sym) ? key.to_sym : key
|
214
|
+
end
|
215
|
+
|
216
|
+
# Set key to true
|
217
|
+
#
|
218
|
+
def key!
|
219
|
+
@_key = true
|
169
220
|
end
|
170
221
|
|
171
222
|
# Delete attributes
|
@@ -177,6 +228,24 @@ module Alba
|
|
177
228
|
@_attributes.delete(attr_name.to_sym)
|
178
229
|
end
|
179
230
|
end
|
231
|
+
|
232
|
+
# Transform keys as specified type
|
233
|
+
#
|
234
|
+
# @param type [String, Symbol]
|
235
|
+
def transform_keys(type)
|
236
|
+
@_transform_keys = type.to_sym
|
237
|
+
end
|
238
|
+
|
239
|
+
# Set error handler
|
240
|
+
#
|
241
|
+
# @param [Symbol] handler
|
242
|
+
# @param [Block]
|
243
|
+
def on_error(handler = nil, &block)
|
244
|
+
raise ArgumentError, 'You cannot specify error handler with both Symbol and block' if handler && block
|
245
|
+
raise ArgumentError, 'You must specify error handler with either Symbol or block' unless handler || block
|
246
|
+
|
247
|
+
@_on_error = handler || block
|
248
|
+
end
|
180
249
|
end
|
181
250
|
end
|
182
251
|
end
|
data/lib/alba/version.rb
CHANGED
data/sider.yml
CHANGED
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.
|
4
|
+
version: 1.0.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:
|
11
|
+
date: 2021-04-15 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
|
@@ -19,25 +19,29 @@ executables: []
|
|
19
19
|
extensions: []
|
20
20
|
extra_rdoc_files: []
|
21
21
|
files:
|
22
|
+
- ".github/workflows/main.yml"
|
22
23
|
- ".gitignore"
|
23
24
|
- ".rubocop.yml"
|
24
|
-
- ".travis.yml"
|
25
25
|
- ".yardopts"
|
26
|
+
- CHANGELOG.md
|
26
27
|
- CODE_OF_CONDUCT.md
|
27
28
|
- Gemfile
|
28
|
-
- Gemfile.lock
|
29
29
|
- LICENSE.txt
|
30
30
|
- README.md
|
31
31
|
- Rakefile
|
32
32
|
- alba.gemspec
|
33
|
+
- benchmark/local.rb
|
33
34
|
- bin/console
|
34
35
|
- bin/setup
|
36
|
+
- gemfiles/all.gemfile
|
37
|
+
- gemfiles/without_active_support.gemfile
|
38
|
+
- gemfiles/without_oj.gemfile
|
35
39
|
- lib/alba.rb
|
36
40
|
- lib/alba/association.rb
|
41
|
+
- lib/alba/key_transformer.rb
|
37
42
|
- lib/alba/many.rb
|
38
43
|
- lib/alba/one.rb
|
39
44
|
- lib/alba/resource.rb
|
40
|
-
- lib/alba/serializer.rb
|
41
45
|
- lib/alba/version.rb
|
42
46
|
- sider.yml
|
43
47
|
homepage: https://github.com/okuramasafumi/alba
|
@@ -46,7 +50,7 @@ licenses:
|
|
46
50
|
metadata:
|
47
51
|
homepage_uri: https://github.com/okuramasafumi/alba
|
48
52
|
source_code_uri: https://github.com/okuramasafumi/alba
|
49
|
-
changelog_uri: https://github.com/okuramasafumi/alba/CHANGELOG.md
|
53
|
+
changelog_uri: https://github.com/okuramasafumi/alba/blob/master/CHANGELOG.md
|
50
54
|
post_install_message:
|
51
55
|
rdoc_options: []
|
52
56
|
require_paths:
|
@@ -55,14 +59,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
55
59
|
requirements:
|
56
60
|
- - ">="
|
57
61
|
- !ruby/object:Gem::Version
|
58
|
-
version: 2.5.
|
62
|
+
version: 2.5.0
|
59
63
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
64
|
requirements:
|
61
65
|
- - ">="
|
62
66
|
- !ruby/object:Gem::Version
|
63
67
|
version: '0'
|
64
68
|
requirements: []
|
65
|
-
rubygems_version: 3.
|
69
|
+
rubygems_version: 3.2.14
|
66
70
|
signing_key:
|
67
71
|
specification_version: 4
|
68
72
|
summary: Alba is the fastest JSON serializer for Ruby.
|
data/.travis.yml
DELETED
data/Gemfile.lock
DELETED
@@ -1,89 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
alba (0.11.1)
|
5
|
-
|
6
|
-
GEM
|
7
|
-
remote: https://rubygems.org/
|
8
|
-
specs:
|
9
|
-
activesupport (6.0.3.2)
|
10
|
-
concurrent-ruby (~> 1.0, >= 1.0.2)
|
11
|
-
i18n (>= 0.7, < 2)
|
12
|
-
minitest (~> 5.1)
|
13
|
-
tzinfo (~> 1.1)
|
14
|
-
zeitwerk (~> 2.2, >= 2.2.2)
|
15
|
-
ast (2.4.1)
|
16
|
-
concurrent-ruby (1.1.6)
|
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.5)
|
25
|
-
concurrent-ruby (~> 1.0)
|
26
|
-
json (2.3.1)
|
27
|
-
minitest (5.14.2)
|
28
|
-
oj (3.10.13)
|
29
|
-
parallel (1.19.2)
|
30
|
-
parser (2.7.1.4)
|
31
|
-
ast (~> 2.4.1)
|
32
|
-
rainbow (3.0.0)
|
33
|
-
rake (13.0.1)
|
34
|
-
regexp_parser (1.7.1)
|
35
|
-
rexml (3.2.4)
|
36
|
-
rubocop (0.90.0)
|
37
|
-
parallel (~> 1.10)
|
38
|
-
parser (>= 2.7.1.1)
|
39
|
-
rainbow (>= 2.2.2, < 4.0)
|
40
|
-
regexp_parser (>= 1.7)
|
41
|
-
rexml
|
42
|
-
rubocop-ast (>= 0.3.0, < 1.0)
|
43
|
-
ruby-progressbar (~> 1.7)
|
44
|
-
unicode-display_width (>= 1.4.0, < 2.0)
|
45
|
-
rubocop-ast (0.3.0)
|
46
|
-
parser (>= 2.7.1.4)
|
47
|
-
rubocop-minitest (0.10.1)
|
48
|
-
rubocop (>= 0.87)
|
49
|
-
rubocop-performance (1.7.1)
|
50
|
-
rubocop (>= 0.82.0)
|
51
|
-
rubocop-sensible (0.3.0)
|
52
|
-
rubocop (>= 0.60.0)
|
53
|
-
ruby-progressbar (1.10.1)
|
54
|
-
simplecov (0.16.1)
|
55
|
-
docile (~> 1.1)
|
56
|
-
json (>= 1.8, < 3)
|
57
|
-
simplecov-html (~> 0.10.0)
|
58
|
-
simplecov-html (0.10.2)
|
59
|
-
sync (0.5.0)
|
60
|
-
term-ansicolor (1.7.1)
|
61
|
-
tins (~> 1.0)
|
62
|
-
thor (1.0.1)
|
63
|
-
thread_safe (0.3.6)
|
64
|
-
tins (1.25.0)
|
65
|
-
sync
|
66
|
-
tzinfo (1.2.7)
|
67
|
-
thread_safe (~> 0.1)
|
68
|
-
unicode-display_width (1.7.0)
|
69
|
-
yard (0.9.25)
|
70
|
-
zeitwerk (2.4.0)
|
71
|
-
|
72
|
-
PLATFORMS
|
73
|
-
ruby
|
74
|
-
|
75
|
-
DEPENDENCIES
|
76
|
-
activesupport
|
77
|
-
alba!
|
78
|
-
coveralls
|
79
|
-
minitest (~> 5.14)
|
80
|
-
oj (~> 3.10)
|
81
|
-
rake (~> 13.0)
|
82
|
-
rubocop (>= 0.79.0)
|
83
|
-
rubocop-minitest (~> 0.10.1)
|
84
|
-
rubocop-performance (~> 1.7.1)
|
85
|
-
rubocop-sensible (~> 0.3.0)
|
86
|
-
yard
|
87
|
-
|
88
|
-
BUNDLED WITH
|
89
|
-
2.1.4
|