Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ sudo: false
language: ruby
cache: bundler
rvm:
- 2.6.3
- 3.2.1
before_install:
- gem install bundler -v 2.0.2
- gem install bundler -v 2.3.7
script:
- bundle exec rspec
38 changes: 19 additions & 19 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,27 @@ PATH
GEM
remote: https://rubygems.org/
specs:
coderay (1.1.2)
diff-lcs (1.3)
google-protobuf (3.11.4)
method_source (0.9.2)
pry (0.12.2)
coderay (~> 1.1.0)
method_source (~> 0.9.0)
rake (13.0.1)
rspec (3.9.0)
rspec-core (~> 3.9.0)
rspec-expectations (~> 3.9.0)
rspec-mocks (~> 3.9.0)
rspec-core (3.9.1)
rspec-support (~> 3.9.1)
rspec-expectations (3.9.0)
coderay (1.1.3)
diff-lcs (1.5.0)
google-protobuf (3.25.1)
method_source (1.0.0)
pry (0.14.2)
coderay (~> 1.1)
method_source (~> 1.0)
rake (13.1.0)
rspec (3.12.0)
rspec-core (~> 3.12.0)
rspec-expectations (~> 3.12.0)
rspec-mocks (~> 3.12.0)
rspec-core (3.12.2)
rspec-support (~> 3.12.0)
rspec-expectations (3.12.3)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.9.0)
rspec-mocks (3.9.1)
rspec-support (~> 3.12.0)
rspec-mocks (3.12.6)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.9.0)
rspec-support (3.9.2)
rspec-support (~> 3.12.0)
rspec-support (3.12.1)

PLATFORMS
ruby
Expand Down
29 changes: 25 additions & 4 deletions lib/pb.rb
Original file line number Diff line number Diff line change
Expand Up @@ -212,13 +212,34 @@ def to_proto_one(klass, v)
type_info = field_types[k.to_s]
next if type_info.nil? # Ignore unknown field

if type_info.type == :message
params[k] = to_proto(type_info.subtype.msgclass, vv)
params[k] = serialize(type_info, vv)
end

klass.new(params)
end

# klass is special _MapEntry_ message class
def to_proto_map(klass, v)
key_descriptor = klass.descriptor.entries.find { |e| e.name == 'key' }
value_descriptor = klass.descriptor.entries.find { |e| e.name == 'value' }
v.to_h do |k, vv|
[
serialize(key_descriptor, k),
serialize(value_descriptor, vv)
]
end
end

def serialize(descriptor, value)
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

better name?

if descriptor.type == :message
if descriptor.subtype.options.map_entry
to_proto_map(descriptor.subtype.msgclass, value)
else
params[k] = to_primitive(type_info.type, vv)
to_proto(descriptor.subtype.msgclass, value)
end
else
to_primitive(descriptor.type, value)
end
klass.new(params)
end

# @param [Symbol] type The type of protobuf field. e.g. :enum, :int64,
Expand Down
61 changes: 61 additions & 0 deletions spec/pb_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,67 @@
)
)
end

end
context "when message entry is a map" do
let(:proto_class_a) {
klass_b = proto_class_b # Assign to variable

# Use random name to avoid conflict
proto_class_name = "proto_class_a_#{Array.new(20) { rand(('a'.ord)..('z'.ord)).chr }.join}"

Google::Protobuf::DescriptorPool.generated_pool.build do
add_message proto_class_name do
map :map_with_primitive_value, :string, :string, 1
map :map_with_message_value, :string, :message, 2, klass_b.descriptor.name
map :map_with_builtin_value, :string, :message, 3, "google.protobuf.Timestamp"
end
end

Google::Protobuf::DescriptorPool.generated_pool.lookup(proto_class_name).msgclass
}
let(:proto_class_b) {
# Use random name to avoid conflict
proto_class_name = "proto_class_b_#{Array.new(20) { rand(('a'.ord)..('z'.ord)).chr }.join}"

Google::Protobuf::DescriptorPool.generated_pool.build do
add_message proto_class_name do
optional :id, :int64, 1
end
end

Google::Protobuf::DescriptorPool.generated_pool.lookup(proto_class_name).msgclass
}

it "returns proto object" do
expect(Pb.to_proto(proto_class_a, {})).to eq proto_class_a.new

expect(Pb.to_proto(proto_class_a, {
map_with_primitive_value: {
"foo": "bar",
},
map_with_message_value: {
"foo": {
"id": 123
},
},
map_with_builtin_value: {
"foo": "2019-02-03T00:00:00+09:00",
}
})).to eq proto_class_a.new({
map_with_primitive_value: {
"foo": "bar",
},
map_with_message_value: {
"foo": {
"id": 123
},
},
map_with_builtin_value: {
"foo": Google::Protobuf::Timestamp.new(seconds: Time.new(2019, 2, 3).to_i),
}
})
end
end
end
end