pb-serializer 0.2.1 → 0.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ed65391a95c2c1d8ebdcd7977c8c8992428c062df0f78c1ba7fbf047737e98e1
4
- data.tar.gz: 1c6db98b94bde534ebbe2999509791b0e2354b15d5ee5bdde17035081e4bf3e2
3
+ metadata.gz: d1f988a05d9e793ea7b9f8e7ce7424f3f0d2f7252c536322c881d7b7921f5c1d
4
+ data.tar.gz: 9136b5e10daa4852db5ade8435d128851e4e1a636eb78fbe612ebca55d47de2a
5
5
  SHA512:
6
- metadata.gz: 7989d54a7f8f699f97387b9dee18ae93e93eb80c745af81802454d34c7b3c262c8b849248ec979a7a1e15e30a1a0a5beabfad816dbd78852198a3d09ce8a0652
7
- data.tar.gz: b9f1e003472b813316869a643ab0214f59eedf1431a998204a57622dffad4287161ff8c57f746d4106b6263ff5cc366c181e948c7ce787de48c98d390ff4c7df
6
+ metadata.gz: 959064c2628dcc51320b6c1fc4e82dffce9f60529740853333198b6a0b9c66db8acfacb5476a9898362a7f7a8fae1e8aa1261ffb32d1d33bd383749645337470
7
+ data.tar.gz: c8f0c9d172cebdbe9f40afca16ec79a62a2c4da32c12821e3420fe36747c6e7a6192d012a029e91427af6cdfb4da65e4f9e82212537e67beefdf8c17bbe04326
@@ -30,3 +30,9 @@ jobs:
30
30
  - run: bundle install --jobs 4 --retry 3
31
31
 
32
32
  - run: bundle exec rspec
33
+ env:
34
+ CI: true
35
+
36
+ - uses: codecov/codecov-action@v1
37
+ with:
38
+ file: ./coverage/coverage.xml
@@ -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
@@ -0,0 +1,6 @@
1
+ coverage:
2
+ status:
3
+ project:
4
+ default:
5
+ target: 95%
6
+ patch: off
@@ -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
- next unless attr # TODO
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 allow_nil [Boolean] Set true if this attribute allow to be nil
95
- # @param serializer [Class] A serializer class for this attribute
96
- def attribute(name, allow_nil: false, serializer: nil)
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
- allow_nil: allow_nil,
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
@@ -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
- :allow_nil,
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)
@@ -1,5 +1,5 @@
1
1
  module Pb
2
2
  module Serializer
3
- VERSION = "0.2.1".freeze
3
+ VERSION = "0.3.0".freeze
4
4
  end
5
5
  end
@@ -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.2.1
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-31 00:00:00.000000000 Z
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