alba 0.2.0 → 0.7.0
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/Gemfile +1 -0
- data/Gemfile.lock +3 -1
- data/README.md +77 -1
- data/lib/alba.rb +21 -18
- data/lib/alba/many.rb +1 -1
- data/lib/alba/one.rb +1 -1
- data/lib/alba/resource.rb +42 -27
- data/lib/alba/resources/default_resource.rb +9 -0
- data/lib/alba/serializer.rb +13 -6
- data/lib/alba/serializers/default_serializer.rb +2 -0
- data/lib/alba/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 405e177e9e1fcadf7dbb164d3ac6924e1b3563547f715fedb698211b527a9604
|
4
|
+
data.tar.gz: 2c534708583345ac9090c83b3ddc939b0c8bd335ed77017f554edb28578d0396
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 71f4712ac28d457fe9bf997fb127288ed66d7d2231ffd6dd438b2eb5c1dd82ff9e3e5c4000415c513012a582cda3d3c3e73fdf0beb4cc96b8583ff9a658dfa75
|
7
|
+
data.tar.gz: '07439ccffc5b48a0d5d4286236acadf4cc3e89ff1afa0a882a87c1fe5640015096a4cd85839cebdc4d6ef350a77043a494bfe4d7b6cff99f8e7db2ab9f8b3db0'
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
alba (0.
|
4
|
+
alba (0.7.0)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
@@ -16,6 +16,7 @@ GEM
|
|
16
16
|
docile (1.3.2)
|
17
17
|
json (2.3.1)
|
18
18
|
minitest (5.14.1)
|
19
|
+
oj (3.10.8)
|
19
20
|
parallel (1.19.2)
|
20
21
|
parser (2.7.1.4)
|
21
22
|
ast (~> 2.4.1)
|
@@ -59,6 +60,7 @@ DEPENDENCIES
|
|
59
60
|
alba!
|
60
61
|
coveralls
|
61
62
|
minitest (~> 5.0)
|
63
|
+
oj (~> 3.10)
|
62
64
|
rake (~> 13.0)
|
63
65
|
rubocop (>= 0.79.0)
|
64
66
|
rubocop-performance (~> 1.7.1)
|
data/README.md
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
# Alba
|
6
6
|
|
7
|
-
`Alba` is a fast and
|
7
|
+
`Alba` is a stupid, fast and easy to use JSON serializer.
|
8
8
|
|
9
9
|
## Installation
|
10
10
|
|
@@ -24,6 +24,8 @@ Or install it yourself as:
|
|
24
24
|
|
25
25
|
## Usage
|
26
26
|
|
27
|
+
### Simple serialization with key
|
28
|
+
|
27
29
|
```ruby
|
28
30
|
class User
|
29
31
|
attr_accessor :id, :name, :email, :created_at, :updated_at
|
@@ -57,6 +59,80 @@ UserResource.new(user).serialize
|
|
57
59
|
# => "{\"id\":1,\"name\":\"Masafumi OKURA\",\"name_with_email\":\"Masafumi OKURA: masafumi@example.com\"}"
|
58
60
|
```
|
59
61
|
|
62
|
+
### Serialization with associations
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
class User
|
66
|
+
attr_reader :id, :created_at, :updated_at
|
67
|
+
attr_accessor :articles
|
68
|
+
|
69
|
+
def initialize(id)
|
70
|
+
@id = id
|
71
|
+
@created_at = Time.now
|
72
|
+
@updated_at = Time.now
|
73
|
+
@articles = []
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
class Article
|
78
|
+
attr_accessor :user_id, :title, :body
|
79
|
+
|
80
|
+
def initialize(user_id, title, body)
|
81
|
+
@user_id = user_id
|
82
|
+
@title = title
|
83
|
+
@body = body
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
class ArticleResource
|
88
|
+
include Alba::Resource
|
89
|
+
|
90
|
+
attributes :title
|
91
|
+
end
|
92
|
+
|
93
|
+
class UserResource1
|
94
|
+
include Alba::Resource
|
95
|
+
|
96
|
+
attributes :id
|
97
|
+
|
98
|
+
many :articles, resource: ArticleResource
|
99
|
+
end
|
100
|
+
|
101
|
+
user = User.new(1)
|
102
|
+
article1 = Article.new(1, 'Hello World!', 'Hello World!!!')
|
103
|
+
user.articles << article1
|
104
|
+
article2 = Article.new(2, 'Super nice', 'Really nice!')
|
105
|
+
user.articles << article2
|
106
|
+
|
107
|
+
UserResource1.new(user).serialize
|
108
|
+
# => '{"id":1,"articles":[{"title":"Hello World!"},{"title":"Super nice"}]}'
|
109
|
+
```
|
110
|
+
|
111
|
+
### Inline definition with `Alba.serialize`
|
112
|
+
|
113
|
+
`Alba.serialize` method is a shortcut to define everything inline.
|
114
|
+
|
115
|
+
```ruby
|
116
|
+
Alba.serialize(user, with: proc { set key: :foo }) do
|
117
|
+
attributes :id
|
118
|
+
many :articles do
|
119
|
+
attributes :title, :body
|
120
|
+
end
|
121
|
+
end
|
122
|
+
# => '{"foo":{"id":1,"articles":[{"title":"Hello World!","body":"Hello World!!!"},{"title":"Super nice","body":"Really nice!"}]}}'
|
123
|
+
```
|
124
|
+
|
125
|
+
Although this might be useful sometimes, it's generally recommended to define a class for both Resource and Serializer.
|
126
|
+
|
127
|
+
## Comparison
|
128
|
+
|
129
|
+
Since Alba is intended to be stupid, there are many things Alba can't do while other gems can. However, from the same reason, it's extremely faster than alternatives.
|
130
|
+
For a performance benchmark, see https://gist.github.com/okuramasafumi/4e375525bd3a28e4ca812d2a3b3e5829.
|
131
|
+
|
132
|
+
## Why named "Alba"?
|
133
|
+
|
134
|
+
The name "Alba" comes from "albatross", a kind of birds. In Japanese, this bird is called "Aho-dori", which means "stupid bird". I find it funny because in fact albatrosses fly really fast. I hope Alba looks stupid but in fact it does its job quick.
|
135
|
+
|
60
136
|
## Development
|
61
137
|
|
62
138
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/lib/alba.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'alba/version'
|
2
|
+
require 'alba/serializers/default_serializer'
|
3
|
+
require 'alba/serializer'
|
2
4
|
require 'alba/resource'
|
3
|
-
require '
|
5
|
+
require 'alba/resources/default_resource'
|
4
6
|
|
5
7
|
# Core module
|
6
8
|
module Alba
|
@@ -8,24 +10,25 @@ module Alba
|
|
8
10
|
|
9
11
|
class << self
|
10
12
|
attr_reader :backend
|
11
|
-
|
13
|
+
attr_accessor :default_serializer
|
12
14
|
|
13
|
-
|
14
|
-
|
15
|
-
|
15
|
+
def backend=(backend)
|
16
|
+
@backend = backend&.to_sym
|
17
|
+
end
|
18
|
+
|
19
|
+
def serialize(object, with: nil, &block)
|
20
|
+
raise ArgumentError, 'Block required' unless block
|
21
|
+
|
22
|
+
resource_class.class_eval(&block)
|
23
|
+
resource = resource_class.new(object)
|
24
|
+
with ||= @default_serializer
|
25
|
+
resource.serialize(with: with)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
16
29
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
when :oj
|
21
|
-
begin
|
22
|
-
require 'oj'
|
23
|
-
->(resource) { Oj.dump(resource) }
|
24
|
-
rescue LoadError
|
25
|
-
fallback
|
26
|
-
end
|
27
|
-
else
|
28
|
-
fallback
|
29
|
-
end.call(object)
|
30
|
+
def resource_class
|
31
|
+
::Alba::Resources::DefaultResource.clone
|
32
|
+
end
|
30
33
|
end
|
31
34
|
end
|
data/lib/alba/many.rb
CHANGED
data/lib/alba/one.rb
CHANGED
data/lib/alba/resource.rb
CHANGED
@@ -7,12 +7,17 @@ require 'alba/serializers/default_serializer'
|
|
7
7
|
module Alba
|
8
8
|
# This module represents what should be serialized
|
9
9
|
module Resource
|
10
|
-
DSLS = [:_attributes, :
|
10
|
+
DSLS = [:_attributes, :_serializer, :_key].freeze
|
11
11
|
def self.included(base)
|
12
12
|
base.class_eval do
|
13
13
|
# Initialize
|
14
14
|
DSLS.each do |name|
|
15
|
-
initial = name
|
15
|
+
initial = case name
|
16
|
+
when :_attributes
|
17
|
+
{}
|
18
|
+
when :_serializer, :_name
|
19
|
+
nil
|
20
|
+
end
|
16
21
|
instance_variable_set("@#{name}", initial) unless instance_variable_defined?("@#{name}")
|
17
22
|
end
|
18
23
|
end
|
@@ -29,41 +34,47 @@ module Alba
|
|
29
34
|
|
30
35
|
def serialize(with: nil)
|
31
36
|
serializer = case with
|
32
|
-
when ->(obj) { obj.is_a?(Class) && obj <= Alba::Serializer }
|
33
|
-
with
|
34
|
-
when Symbol
|
35
|
-
const_get(with.to_s.capitalize)
|
36
|
-
when String
|
37
|
-
const_get(with)
|
38
37
|
when nil
|
39
38
|
@_serializer || Alba::Serializers::DefaultSerializer
|
39
|
+
when ->(obj) { obj.is_a?(Class) && obj <= Alba::Serializer }
|
40
|
+
with
|
41
|
+
when Proc
|
42
|
+
inline_extended_serializer(with)
|
43
|
+
else
|
44
|
+
raise ArgumentError, 'Unexpected type for with, possible types are Class or Proc'
|
40
45
|
end
|
41
|
-
serializer.new(
|
46
|
+
serializer.new(self).serialize
|
42
47
|
end
|
43
48
|
|
44
|
-
def serializable_hash
|
45
|
-
|
49
|
+
def serializable_hash(with_key: true)
|
50
|
+
get_attribute = lambda do |resource|
|
51
|
+
@_attributes.transform_values do |attribute|
|
52
|
+
attribute.to_hash(resource)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
serializable_hash = if collection?
|
56
|
+
@_resource.map(&get_attribute)
|
57
|
+
else
|
58
|
+
get_attribute.call(@_resource)
|
59
|
+
end
|
60
|
+
with_key && @_key ? {@_key => serializable_hash} : serializable_hash
|
46
61
|
end
|
47
62
|
alias to_hash serializable_hash
|
48
63
|
|
49
|
-
|
50
|
-
|
51
|
-
def attrs
|
52
|
-
@_attributes.transform_values do |attribute|
|
53
|
-
attribute.to_hash(@_resource)
|
54
|
-
end || {}
|
64
|
+
def key
|
65
|
+
@_key || self.class.name.delete_suffix('Resource').downcase.gsub(/:{2}/, '_').to_sym
|
55
66
|
end
|
56
67
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
68
|
+
private
|
69
|
+
|
70
|
+
def inline_extended_serializer(with)
|
71
|
+
klass = ::Alba::Serializers::DefaultSerializer.clone
|
72
|
+
klass.class_eval(&with)
|
73
|
+
klass
|
61
74
|
end
|
62
75
|
|
63
|
-
def
|
64
|
-
@
|
65
|
-
many.to_hash(@_resource)
|
66
|
-
end || {}
|
76
|
+
def collection?
|
77
|
+
@_resource.is_a?(Enumerable)
|
67
78
|
end
|
68
79
|
end
|
69
80
|
|
@@ -86,16 +97,20 @@ module Alba
|
|
86
97
|
end
|
87
98
|
|
88
99
|
def one(name, resource: nil, &block)
|
89
|
-
@
|
100
|
+
@_attributes[name.to_sym] = One.new(name: name, resource: resource, &block)
|
90
101
|
end
|
91
102
|
|
92
103
|
def many(name, resource: nil, &block)
|
93
|
-
@
|
104
|
+
@_attributes[name.to_sym] = Many.new(name: name, resource: resource, &block)
|
94
105
|
end
|
95
106
|
|
96
107
|
def serializer(name)
|
97
108
|
@_serializer = name <= Alba::Serializer ? name : nil
|
98
109
|
end
|
110
|
+
|
111
|
+
def key(key)
|
112
|
+
@_key = key.to_sym
|
113
|
+
end
|
99
114
|
end
|
100
115
|
end
|
101
116
|
end
|
data/lib/alba/serializer.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
module Alba
|
2
2
|
# This module represents how a resource should be serialized.
|
3
|
-
#
|
4
3
|
module Serializer
|
5
4
|
def self.included(base)
|
6
5
|
base.include InstanceMethods
|
@@ -10,19 +9,27 @@ module Alba
|
|
10
9
|
# Instance methods
|
11
10
|
module InstanceMethods
|
12
11
|
def initialize(resource)
|
13
|
-
@_resource = resource
|
14
12
|
@_opts = self.class._opts || {}
|
15
|
-
key = @_opts[:key]
|
16
|
-
|
13
|
+
key = case @_opts[:key]
|
14
|
+
when true
|
15
|
+
resource.key
|
16
|
+
else
|
17
|
+
@_opts[:key]
|
18
|
+
end
|
19
|
+
@hash = resource.serializable_hash(with_key: false)
|
20
|
+
@hash = {key.to_sym => @hash} if key
|
17
21
|
end
|
18
22
|
|
19
23
|
def serialize
|
20
|
-
fallback =
|
24
|
+
fallback = lambda do
|
25
|
+
require 'json'
|
26
|
+
JSON.dump(@hash)
|
27
|
+
end
|
21
28
|
case Alba.backend
|
22
29
|
when :oj
|
23
30
|
begin
|
24
31
|
require 'oj'
|
25
|
-
-> { Oj.dump(@
|
32
|
+
-> { Oj.dump(@hash, mode: :strict) }
|
26
33
|
rescue LoadError
|
27
34
|
fallback
|
28
35
|
end
|
data/lib/alba/version.rb
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: 0.7.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: 2020-07-
|
11
|
+
date: 2020-07-31 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Fast and flexible JSON serializer
|
14
14
|
email:
|
@@ -34,6 +34,7 @@ files:
|
|
34
34
|
- lib/alba/many.rb
|
35
35
|
- lib/alba/one.rb
|
36
36
|
- lib/alba/resource.rb
|
37
|
+
- lib/alba/resources/default_resource.rb
|
37
38
|
- lib/alba/serializer.rb
|
38
39
|
- lib/alba/serializers/default_serializer.rb
|
39
40
|
- lib/alba/version.rb
|