aboutsummaryrefslogtreecommitdiffhomepage
path: root/ruby
diff options
context:
space:
mode:
authorGravatar Zachary Anker <zanker@squareup.com>2017-09-14 08:35:13 -0700
committerGravatar Zachary Anker <zanker@squareup.com>2017-09-20 11:38:05 -0700
commit83264bd160326fe808c2d5bfbebe54e77f781152 (patch)
tree68c4391f0cbf1a6fcdda11e4028a66af108f87e5 /ruby
parentd1bc27caef8377a710370189675cb0958443e8f1 (diff)
Fixed to_h with repeated messages to return hashes in Ruby
Diffstat (limited to 'ruby')
-rw-r--r--ruby/ext/google/protobuf_c/message.c7
-rw-r--r--ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java14
-rw-r--r--ruby/tests/basic.rb4
3 files changed, 22 insertions, 3 deletions
diff --git a/ruby/ext/google/protobuf_c/message.c b/ruby/ext/google/protobuf_c/message.c
index 29911140..82c730b5 100644
--- a/ruby/ext/google/protobuf_c/message.c
+++ b/ruby/ext/google/protobuf_c/message.c
@@ -419,6 +419,13 @@ VALUE Message_to_h(VALUE _self) {
msg_value = Map_to_h(msg_value);
} else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
msg_value = RepeatedField_to_ary(msg_value);
+
+ if (upb_fieldddef_type(field) == UPB_TYPE_MESSAGE) {
+ for (int i = 0; i < RARRAY_LEN(msg_value); i++) {
+ VALUE elem = rb_ary_entry(msg_value, i);
+ rb_ary_store(msg_value, i, Message_to_h(elem));
+ }
+ }
} else if (msg_value != Qnil &&
upb_fielddef_type(field) == UPB_TYPE_MESSAGE) {
msg_value = Message_to_h(msg_value);
diff --git a/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java b/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java
index 733ccfbc..0cdb67fe 100644
--- a/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java
+++ b/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java
@@ -367,7 +367,19 @@ public class RubyMessage extends RubyObject {
for (Descriptors.FieldDescriptor fdef : this.descriptor.getFields()) {
IRubyObject value = getField(context, fdef);
if (!value.isNil()) {
- if (value.respondsTo("to_h")) {
+ if (fdef.isRepeated() && !fdef.isMapField()) {
+ if (fdef.getType() != Descriptors.FieldDescriptor.Type.MESSAGE) {
+ value = Helpers.invoke(context, value, "to_a");
+ } else {
+ RubyArray ary = value.convertToArray();
+ for (int i = 0; i < ary.size(); i++) {
+ IRubyObject submsg = Helpers.invoke(context, ary.eltInternal(i), "to_h");
+ ary.eltInternalSet(i, submsg);
+ }
+
+ value = ary.to_ary();
+ }
+ } else if (value.respondsTo("to_h")) {
value = Helpers.invoke(context, value, "to_h");
} else if (value.respondsTo("to_a")) {
value = Helpers.invoke(context, value, "to_a");
diff --git a/ruby/tests/basic.rb b/ruby/tests/basic.rb
index 94071ca0..3b8ca1fa 100644
--- a/ruby/tests/basic.rb
+++ b/ruby/tests/basic.rb
@@ -927,7 +927,7 @@ module BasicTest
end
def test_to_h
- m = TestMessage.new(:optional_bool => true, :optional_double => -10.100001, :optional_string => 'foo', :repeated_string => ['bar1', 'bar2'])
+ m = TestMessage.new(:optional_bool => true, :optional_double => -10.100001, :optional_string => 'foo', :repeated_string => ['bar1', 'bar2'], :repeated_msg => [TestMessage2.new(:foo => 100)])
expected_result = {
:optional_bool=>true,
:optional_bytes=>"",
@@ -947,7 +947,7 @@ module BasicTest
:repeated_float=>[],
:repeated_int32=>[],
:repeated_int64=>[],
- :repeated_msg=>[],
+ :repeated_msg=>[{:foo => 100}],
:repeated_string=>["bar1", "bar2"],
:repeated_uint32=>[],
:repeated_uint64=>[]