pb-serializer 0.1.0 → 0.2.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/README.md +17 -11
- data/lib/pb/serializable.rb +53 -19
- data/lib/pb/serializer/attribute.rb +1 -1
- data/lib/pb/serializer/base.rb +13 -0
- data/lib/pb/serializer/version.rb +1 -1
- data/pb-serializer.gemspec +1 -1
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3d65ab2cd7830751ed61e5cd72eca1d688fac910b544167994780d065e55fa3b
|
4
|
+
data.tar.gz: e991534beffa6fb92b4c23f05bf59b5ba0ef6872cd34dc801148e08ec3f2c075
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0a138f78df718b226cbf65cef851380a941c34306ed80bdc2fb65093f0dec804515d0187d3f0b11e4fcd36bbc339dfca08f2beef49989d6417ccf157ddf9da97
|
7
|
+
data.tar.gz: bf343a1d3f7f055370f652616fc6914dc682f2fdc6840c6975614537d5ecf02241974b8df986505f96a517401b676e0756aa2040d181898e8dc866ee76ab305c
|
data/README.md
CHANGED
@@ -6,24 +6,29 @@ class UserSerializer < Pb::Serializer::Base
|
|
6
6
|
|
7
7
|
attribute :id, required: true
|
8
8
|
attribute :name, required: true
|
9
|
-
attribute :posts, required: true
|
9
|
+
attribute :posts, required: true
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
11
|
+
define_primary_loader :user do |subdeps, ids:, **|
|
12
|
+
User.where(id: ids).preload(subdeps).map { |u| new(u) }
|
13
|
+
end
|
14
|
+
|
15
|
+
define_loader :posts, key: -> { id } do |user_ids, subdeps, **|
|
16
|
+
PostSerializer.bulk_load(user_id: user_ids, with: subdeps).group_by { |s| s.post.user_id }
|
16
17
|
end
|
17
18
|
|
18
19
|
dependency :posts
|
19
20
|
computed def post_count
|
20
|
-
|
21
|
+
posts.count
|
21
22
|
end
|
22
23
|
end
|
23
24
|
|
24
25
|
class PostSerializer < Pb::Serializer::Base
|
25
26
|
message YourApp::Post
|
26
27
|
|
28
|
+
define_primary_loader :post do |subdeps, user_ids:, **|
|
29
|
+
Post.where(user_id: user_ids).preload(subdeps).map { |p| new(p) }
|
30
|
+
end
|
31
|
+
|
27
32
|
attribute :id, required: true
|
28
33
|
attribute :title, required: true
|
29
34
|
attribute :body, required: true
|
@@ -34,22 +39,23 @@ class UserGrpcService < YourApp::UserService::Service
|
|
34
39
|
# @param call [GRPC::ActiveCall::SingleReqView]
|
35
40
|
# @return [YourApp::User]
|
36
41
|
def get_users(req, call)
|
37
|
-
|
38
|
-
UserSerializer.serialize(user, with: req.field_mask)
|
42
|
+
UserSerializer.bulk_load_and_serialize(ids: [req.user_id], with: req.field_mask)[0]
|
39
43
|
end
|
40
44
|
|
41
45
|
# @param req [YourApp::ListFriendUsersRequest]
|
42
46
|
# @param call [GRPC::ActiveCall::SingleReqView]
|
43
47
|
# @return [YourApp::ListFriendUsersResponse]
|
44
48
|
def list_friend_users(req, call)
|
45
|
-
|
49
|
+
current_user = User.find(current_user_id)
|
46
50
|
YourApp::ListFriendUsersResponse.new(
|
47
|
-
users: UserSerializer.
|
51
|
+
users: UserSerializer.bulk_load_and_serialize(ids: current_user.friend_ids, with: req.field_mask)
|
48
52
|
)
|
49
53
|
end
|
50
54
|
end
|
51
55
|
```
|
52
56
|
|
57
|
+
More examples are available under [./spec/examples](./spec/examples).
|
58
|
+
|
53
59
|
|
54
60
|
## Installation
|
55
61
|
|
data/lib/pb/serializable.rb
CHANGED
@@ -3,14 +3,11 @@ module Pb
|
|
3
3
|
def self.included(base)
|
4
4
|
base.extend ClassMethods
|
5
5
|
base.include ComputedModel
|
6
|
+
base.singleton_class.prepend Hook
|
6
7
|
end
|
7
8
|
|
8
9
|
def to_pb(with: nil)
|
9
|
-
|
10
|
-
with = ::Pb::Serializer.build_default_mask(self.class.message_class.descriptor)
|
11
|
-
end
|
12
|
-
|
13
|
-
self.class.bulk_load_and_compute(Array(self), with)
|
10
|
+
# TODO: apply masks
|
14
11
|
|
15
12
|
oneof_set = []
|
16
13
|
|
@@ -26,14 +23,14 @@ module Pb
|
|
26
23
|
v = attr.convert_to_pb(v)
|
27
24
|
|
28
25
|
if attr.required && attr.field_descriptor.default == v
|
29
|
-
raise ::Pb::Serializer::ValidationError, "#{
|
26
|
+
raise ::Pb::Serializer::ValidationError, "#{primary_object.class.name}##{attr.name} is required"
|
30
27
|
end
|
31
28
|
|
32
29
|
next if v.nil?
|
33
30
|
|
34
31
|
if attr.oneof?
|
35
32
|
if oneof_set.include?(attr.oneof)
|
36
|
-
raise ::Pb::Serializer::ConflictOneofError, "#{
|
33
|
+
raise ::Pb::Serializer::ConflictOneofError, "#{primary_object.class.name}##{attr.name} is oneof attribute"
|
37
34
|
end
|
38
35
|
oneof_set << attr.oneof
|
39
36
|
end
|
@@ -48,14 +45,47 @@ module Pb
|
|
48
45
|
self.class.oneofs.each do |oneof|
|
49
46
|
next if oneof_set.include?(oneof.name)
|
50
47
|
next unless oneof.required?
|
51
|
-
raise ::Pb::Serializer::ValidationError, "#{
|
48
|
+
raise ::Pb::Serializer::ValidationError, "#{primary_object.class.name}##{oneof.name} is required"
|
52
49
|
end
|
53
50
|
|
54
51
|
o
|
55
52
|
end
|
56
53
|
|
54
|
+
private def primary_object
|
55
|
+
primary_object_name = self.class.__pb_serializer_primary_model_name
|
56
|
+
if primary_object_name
|
57
|
+
send(primary_object_name)
|
58
|
+
elsif kind_of?(Serializer::Base)
|
59
|
+
send(:object)
|
60
|
+
else
|
61
|
+
self
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
module Hook
|
66
|
+
def define_primary_loader(name)
|
67
|
+
self.__pb_serializer_primary_model_name = name
|
68
|
+
|
69
|
+
super
|
70
|
+
end
|
71
|
+
|
72
|
+
def computed(name)
|
73
|
+
__pb_serializer_attrs << name
|
74
|
+
|
75
|
+
super
|
76
|
+
end
|
77
|
+
|
78
|
+
def define_loader(name, **)
|
79
|
+
__pb_serializer_attrs << name
|
80
|
+
|
81
|
+
super
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
57
85
|
module ClassMethods
|
58
86
|
attr_reader :message_class
|
87
|
+
attr_accessor :__pb_serializer_primary_model_name
|
88
|
+
|
59
89
|
def message(klass)
|
60
90
|
@message_class = klass
|
61
91
|
end
|
@@ -79,21 +109,21 @@ module Pb
|
|
79
109
|
@attr_by_name[name] = attr
|
80
110
|
|
81
111
|
define_method attr.name do
|
82
|
-
|
112
|
+
primary_object.public_send(attr.name)
|
83
113
|
end
|
114
|
+
end
|
84
115
|
|
85
|
-
|
86
|
-
|
116
|
+
# @param with [Array, Google::Protobuf::FieldMask, nil]
|
117
|
+
# @return [Array]
|
118
|
+
def bulk_load_and_serialize(with: nil, **args)
|
119
|
+
bulk_load(with: with, **args).map { |s| s.to_pb(with: with) }
|
87
120
|
end
|
88
121
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
else
|
95
|
-
object.to_pb
|
96
|
-
end
|
122
|
+
def bulk_load(with: nil, **args)
|
123
|
+
with ||= ::Pb::Serializer.build_default_mask(message_class.descriptor)
|
124
|
+
with = with.reject { |c| (__pb_serializer_attrs & (c.kind_of?(Hash) ? c.keys : [c])).empty? }
|
125
|
+
|
126
|
+
bulk_load_and_compute(with, **args)
|
97
127
|
end
|
98
128
|
|
99
129
|
def oneof(name, required: true)
|
@@ -108,6 +138,10 @@ module Pb
|
|
108
138
|
@current_oneof = nil
|
109
139
|
end
|
110
140
|
|
141
|
+
private def __pb_serializer_attrs
|
142
|
+
@__pb_serializer_attrs ||= Set.new
|
143
|
+
end
|
144
|
+
|
111
145
|
# @param fd [Google::Protobuf::FieldDescriptor] a field descriptor
|
112
146
|
# @return [Pb::Serializer::Attribute, nil]
|
113
147
|
def find_attribute_by_field_descriptor(fd)
|
@@ -42,7 +42,7 @@ module Pb
|
|
42
42
|
when "google.protobuf.BytesValue" then Pb.to_bytesval(v)
|
43
43
|
else
|
44
44
|
return nil if v.nil?
|
45
|
-
return serializer_class.
|
45
|
+
return serializer_class.new(v).to_pb if serializer_class
|
46
46
|
return v.to_pb if v.kind_of?(::Pb::Serializable)
|
47
47
|
|
48
48
|
raise "serializer was not found for #{field_descriptor.submsg_name}"
|
data/lib/pb/serializer/base.rb
CHANGED
@@ -3,6 +3,7 @@ module Pb
|
|
3
3
|
class Base
|
4
4
|
def self.inherited(base)
|
5
5
|
base.include ::Pb::Serializable
|
6
|
+
base.singleton_class.prepend Hook
|
6
7
|
end
|
7
8
|
|
8
9
|
attr_reader :object
|
@@ -10,6 +11,18 @@ module Pb
|
|
10
11
|
def initialize(object)
|
11
12
|
@object = object
|
12
13
|
end
|
14
|
+
|
15
|
+
module Hook
|
16
|
+
def define_primary_loader(name, &block)
|
17
|
+
class_eval <<~RUBY
|
18
|
+
def initialize(object)
|
19
|
+
@#{name} = object
|
20
|
+
end
|
21
|
+
RUBY
|
22
|
+
|
23
|
+
super
|
24
|
+
end
|
25
|
+
end
|
13
26
|
end
|
14
27
|
end
|
15
28
|
end
|
data/pb-serializer.gemspec
CHANGED
@@ -29,7 +29,7 @@ Gem::Specification.new do |spec|
|
|
29
29
|
rails_versions = [">= 5.2", "< 6.1"]
|
30
30
|
spec.add_runtime_dependency "google-protobuf", "~> 3.0"
|
31
31
|
spec.add_runtime_dependency "the_pb", "~> 0.0.1"
|
32
|
-
spec.add_runtime_dependency "computed_model", "~> 0.1
|
32
|
+
spec.add_runtime_dependency "computed_model", "~> 0.2.1"
|
33
33
|
|
34
34
|
spec.add_development_dependency "activerecord", rails_versions
|
35
35
|
spec.add_development_dependency "bundler", "~> 2.0"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pb-serializer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- izumin5210
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-03-
|
11
|
+
date: 2020-03-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: google-protobuf
|
@@ -44,14 +44,14 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 0.1
|
47
|
+
version: 0.2.1
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 0.1
|
54
|
+
version: 0.2.1
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: activerecord
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -205,7 +205,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
205
205
|
- !ruby/object:Gem::Version
|
206
206
|
version: '0'
|
207
207
|
requirements: []
|
208
|
-
rubygems_version: 3.
|
208
|
+
rubygems_version: 3.1.2
|
209
209
|
signing_key:
|
210
210
|
specification_version: 4
|
211
211
|
summary: Serialize objects into Protocol Buffers messages
|