pb-serializer 0.2.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +6 -0
- data/CHANGELOG.md +13 -0
- data/README.md +4 -0
- data/codecov.yml +6 -0
- data/lib/pb/serializable.rb +22 -7
- data/lib/pb/serializer.rb +47 -0
- data/lib/pb/serializer/attribute.rb +35 -3
- data/lib/pb/serializer/version.rb +1 -1
- data/pb-serializer.gemspec +2 -0
- metadata +31 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d1f988a05d9e793ea7b9f8e7ce7424f3f0d2f7252c536322c881d7b7921f5c1d
|
4
|
+
data.tar.gz: 9136b5e10daa4852db5ade8435d128851e4e1a636eb78fbe612ebca55d47de2a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 959064c2628dcc51320b6c1fc4e82dffce9f60529740853333198b6a0b9c66db8acfacb5476a9898362a7f7a8fae1e8aa1261ffb32d1d33bd383749645337470
|
7
|
+
data.tar.gz: c8f0c9d172cebdbe9f40afca16ec79a62a2c4da32c12821e3420fe36747c6e7a6192d012a029e91427af6cdfb4da65e4f9e82212537e67beefdf8c17bbe04326
|
data/.github/workflows/ci.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,18 @@
|
|
1
1
|
## Unreleased
|
2
2
|
|
3
|
+
## 0.3.0
|
4
|
+
|
5
|
+
- Support `if` option https://github.com/wantedly/pb-serializer/pull/24
|
6
|
+
- Improve error handling https://github.com/wantedly/pb-serializer/pull/26
|
7
|
+
- raise `MissingMessageTypeError` if `message` declaration is missed
|
8
|
+
- raise `MissingFieldError` if `attribute` declaration is missed
|
9
|
+
- raise `InvalidOptionError` when `attribute` receives invalid params
|
10
|
+
- Introduce Pb::Serializer.configure https://github.com/wantedly/pb-serializer/pull/27
|
11
|
+
- Add `missing_field_behavior` config to suppress `MissingFieldError`
|
12
|
+
- Rename `InvalidOptionError` -> `InvalidAttributeOptionError`
|
13
|
+
- Skip serializing when a value is already serialized https://github.com/wantedly/pb-serializer/pull/29
|
14
|
+
|
15
|
+
|
3
16
|
## 0.2.1
|
4
17
|
|
5
18
|
- **BREAKING CHANGE** `required` -> `allow_nil` https://github.com/wantedly/pb-serializer/pull/21
|
data/README.md
CHANGED
@@ -1,4 +1,8 @@
|
|
1
1
|
# Pb::Serializer
|
2
|
+
[![CI](https://github.com/wantedly/pb-serializer/workflows/CI/badge.svg?branch=master)](https://github.com/wantedly/pb-serializer/actions?query=workflow%3ACI+branch%3Amaster)
|
3
|
+
[![codecov](https://codecov.io/gh/wantedly/pb-serializer/branch/master/graph/badge.svg)](https://codecov.io/gh/wantedly/pb-serializer)
|
4
|
+
[![Gem Version](https://badge.fury.io/rb/pb-serializer.svg)](https://badge.fury.io/rb/pb-serializer)
|
5
|
+
[![License](https://img.shields.io/github/license/wantedly/pb-serializer)](./LICENSE)
|
2
6
|
|
3
7
|
```rb
|
4
8
|
class UserSerializer < Pb::Serializer::Base
|
data/codecov.yml
ADDED
data/lib/pb/serializable.rb
CHANGED
@@ -15,7 +15,18 @@ module Pb
|
|
15
15
|
self.class.message_class.descriptor.each do |fd|
|
16
16
|
attr = self.class.find_attribute_by_field_descriptor(fd)
|
17
17
|
|
18
|
-
|
18
|
+
unless attr
|
19
|
+
msg = "#{self.class.message_class.name}.#{fd.name} is missed in #{self.class.name}"
|
20
|
+
|
21
|
+
case Pb::Serializer.configuration.missing_field_behavior
|
22
|
+
when :raise then raise ::Pb::Serializer::MissingFieldError, msg
|
23
|
+
when :warn then Pb::Serializer.logger.warn msg
|
24
|
+
end
|
25
|
+
|
26
|
+
next
|
27
|
+
end
|
28
|
+
|
29
|
+
next unless attr.serializable?(self)
|
19
30
|
|
20
31
|
raise "#{self.name}.#{attr.name} is not defined" unless respond_to?(attr.name)
|
21
32
|
|
@@ -91,16 +102,20 @@ module Pb
|
|
91
102
|
end
|
92
103
|
|
93
104
|
# @param name [Symbol] An attribute name
|
94
|
-
# @param
|
95
|
-
# @
|
96
|
-
|
105
|
+
# @param [Hash] opts options
|
106
|
+
# @option opts [Boolean] :allow_nil Set true if this attribute allow to be nil
|
107
|
+
# @option opts [Class] :serializer A serializer class for this attribute
|
108
|
+
# @option opts [String, Symbol, Proc] :if A method, proc or string to call to determine to serialize this field
|
109
|
+
def attribute(name, opts = {})
|
110
|
+
raise ::Pb::Serializer::MissingMessageTypeError, "message specificaiton is missed" unless message_class
|
111
|
+
|
97
112
|
fd = message_class.descriptor.find { |fd| fd.name.to_sym == name }
|
113
|
+
|
98
114
|
raise ::Pb::Serializer::UnknownFieldError, "#{name} is not defined in #{message_class.name}" unless fd
|
99
115
|
|
100
116
|
attr = ::Pb::Serializer::Attribute.new(
|
101
117
|
name: name,
|
102
|
-
|
103
|
-
serializer_class: serializer,
|
118
|
+
options: opts,
|
104
119
|
field_descriptor: fd,
|
105
120
|
oneof: @current_oneof&.name,
|
106
121
|
)
|
@@ -145,7 +160,7 @@ module Pb
|
|
145
160
|
# @param fd [Google::Protobuf::FieldDescriptor] a field descriptor
|
146
161
|
# @return [Pb::Serializer::Attribute, nil]
|
147
162
|
def find_attribute_by_field_descriptor(fd)
|
148
|
-
@attr_by_name[fd.name.to_sym]
|
163
|
+
(@attr_by_name || {})[fd.name.to_sym]
|
149
164
|
end
|
150
165
|
|
151
166
|
def oneofs
|
data/lib/pb/serializer.rb
CHANGED
@@ -10,11 +10,58 @@ require "pb/serializer/oneof"
|
|
10
10
|
module Pb
|
11
11
|
module Serializer
|
12
12
|
class Error < StandardError; end
|
13
|
+
class InvalidConfigurationError < Error; end
|
14
|
+
class MissingMessageTypeError < Error; end
|
13
15
|
class UnknownFieldError < Error; end
|
14
16
|
class ValidationError < Error; end
|
15
17
|
class ConflictOneofError < Error; end
|
18
|
+
class InvalidAttributeOptionError < Error; end
|
19
|
+
class MissingFieldError < Error; end
|
20
|
+
|
21
|
+
class Configuration
|
22
|
+
# @!attribute logger
|
23
|
+
# @return [Logger]
|
24
|
+
attr_accessor :logger
|
25
|
+
# @!attribute [r] missing_field_behavior
|
26
|
+
# @return [:raise, :warn, :ignore] default: `:raise`
|
27
|
+
attr_reader :missing_field_behavior
|
28
|
+
|
29
|
+
def initialize
|
30
|
+
self.missing_field_behavior = :raise
|
31
|
+
self.logger = Logger.new(STDOUT)
|
32
|
+
end
|
33
|
+
|
34
|
+
# @param v [:raise, :warn, :ignore]
|
35
|
+
def missing_field_behavior=(v)
|
36
|
+
@missing_field_behavior = v
|
37
|
+
|
38
|
+
unless %i(raise warn ignore).include?(v)
|
39
|
+
raise InvalidConfigurationError, "missing_field_behavior #{v} is not allowed"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
16
43
|
|
17
44
|
class << self
|
45
|
+
# @example
|
46
|
+
# Pb::Serializer.configuration do |c|
|
47
|
+
# c.missing_field_behavior = :raise # :raise, :warn or :ignore (defualt: :raise)
|
48
|
+
# end
|
49
|
+
# @yield [c]
|
50
|
+
# @yieldparam [Configuration] config
|
51
|
+
def configure
|
52
|
+
yield configuration
|
53
|
+
end
|
54
|
+
|
55
|
+
# @return [Pb::Serializer::Configuration]
|
56
|
+
def configuration
|
57
|
+
@configuraiton ||= Configuration.new
|
58
|
+
end
|
59
|
+
|
60
|
+
# @return [Logger]
|
61
|
+
def logger
|
62
|
+
configuration.logger
|
63
|
+
end
|
64
|
+
|
18
65
|
# @param [Google::Protobuf::Descriptor]
|
19
66
|
def build_default_mask(descriptor)
|
20
67
|
set =
|
@@ -2,16 +2,31 @@ module Pb
|
|
2
2
|
module Serializer
|
3
3
|
class Attribute < Struct.new(
|
4
4
|
:name,
|
5
|
-
:
|
6
|
-
:serializer_class,
|
5
|
+
:options,
|
7
6
|
:field_descriptor,
|
8
7
|
:oneof,
|
9
8
|
keyword_init: true,
|
10
9
|
)
|
11
10
|
|
11
|
+
ALLOWED_OPTIONS = Set[:allow_nil, :if, :serializer].freeze
|
12
|
+
|
13
|
+
def initialize(options:, **)
|
14
|
+
super
|
15
|
+
|
16
|
+
unknown_options = options.keys.to_set - ALLOWED_OPTIONS
|
17
|
+
unless unknown_options.empty?
|
18
|
+
raise InvalidAttributeOptionError, "unknown options are specified in #{name} attribute: #{unknown_options.to_a}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
12
22
|
# @return [Boolean]
|
13
23
|
def allow_nil?
|
14
|
-
allow_nil
|
24
|
+
options.fetch(:allow_nil, false)
|
25
|
+
end
|
26
|
+
|
27
|
+
# @return [Class]
|
28
|
+
def serializer_class
|
29
|
+
options[:serializer]
|
15
30
|
end
|
16
31
|
|
17
32
|
# @return [Boolean]
|
@@ -19,6 +34,19 @@ module Pb
|
|
19
34
|
field_descriptor.label == :repeated
|
20
35
|
end
|
21
36
|
|
37
|
+
# @return [Boolean]
|
38
|
+
def serializable?(s)
|
39
|
+
cond = options[:if]
|
40
|
+
|
41
|
+
return true unless cond
|
42
|
+
|
43
|
+
case cond
|
44
|
+
when String, Symbol; then s.send(cond)
|
45
|
+
when Proc; then s.instance_exec(&cond)
|
46
|
+
else raise InvalidAttributeOptionError, "`if` option can accept only Symbol, String or Proc. but got #{cond.class}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
22
50
|
def oneof?
|
23
51
|
!oneof.nil?
|
24
52
|
end
|
@@ -30,6 +58,10 @@ module Pb
|
|
30
58
|
|
31
59
|
case field_descriptor.type
|
32
60
|
when :message
|
61
|
+
if v.class < Google::Protobuf::MessageExts && v.class.descriptor.name == field_descriptor.submsg_name
|
62
|
+
return v
|
63
|
+
end
|
64
|
+
|
33
65
|
case field_descriptor.submsg_name
|
34
66
|
when "google.protobuf.Timestamp" then Pb.to_timestamp(v)
|
35
67
|
when "google.protobuf.StringValue" then Pb.to_strval(v)
|
data/pb-serializer.gemspec
CHANGED
@@ -38,4 +38,6 @@ Gem::Specification.new do |spec|
|
|
38
38
|
spec.add_development_dependency "rspec", "~> 3.0"
|
39
39
|
spec.add_development_dependency "rubocop", "0.67.2" # for onkcop
|
40
40
|
spec.add_development_dependency "sqlite3", "~> 1.4"
|
41
|
+
spec.add_development_dependency "simplecov", "~> 0.18.5"
|
42
|
+
spec.add_development_dependency "simplecov-cobertura", "~> 1.3"
|
41
43
|
end
|
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.3.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-04-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: google-protobuf
|
@@ -156,6 +156,34 @@ dependencies:
|
|
156
156
|
- - "~>"
|
157
157
|
- !ruby/object:Gem::Version
|
158
158
|
version: '1.4'
|
159
|
+
- !ruby/object:Gem::Dependency
|
160
|
+
name: simplecov
|
161
|
+
requirement: !ruby/object:Gem::Requirement
|
162
|
+
requirements:
|
163
|
+
- - "~>"
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: 0.18.5
|
166
|
+
type: :development
|
167
|
+
prerelease: false
|
168
|
+
version_requirements: !ruby/object:Gem::Requirement
|
169
|
+
requirements:
|
170
|
+
- - "~>"
|
171
|
+
- !ruby/object:Gem::Version
|
172
|
+
version: 0.18.5
|
173
|
+
- !ruby/object:Gem::Dependency
|
174
|
+
name: simplecov-cobertura
|
175
|
+
requirement: !ruby/object:Gem::Requirement
|
176
|
+
requirements:
|
177
|
+
- - "~>"
|
178
|
+
- !ruby/object:Gem::Version
|
179
|
+
version: '1.3'
|
180
|
+
type: :development
|
181
|
+
prerelease: false
|
182
|
+
version_requirements: !ruby/object:Gem::Requirement
|
183
|
+
requirements:
|
184
|
+
- - "~>"
|
185
|
+
- !ruby/object:Gem::Version
|
186
|
+
version: '1.3'
|
159
187
|
description: Serialize objects into Protocol Buffers messages
|
160
188
|
email:
|
161
189
|
- m@izum.in
|
@@ -177,6 +205,7 @@ files:
|
|
177
205
|
- Rakefile
|
178
206
|
- bin/console
|
179
207
|
- bin/setup
|
208
|
+
- codecov.yml
|
180
209
|
- lib/pb/serializable.rb
|
181
210
|
- lib/pb/serializer.rb
|
182
211
|
- lib/pb/serializer/attribute.rb
|