From 83264bd160326fe808c2d5bfbebe54e77f781152 Mon Sep 17 00:00:00 2001 From: Zachary Anker Date: Thu, 14 Sep 2017 08:35:13 -0700 Subject: Fixed to_h with repeated messages to return hashes in Ruby --- ruby/ext/google/protobuf_c/message.c | 7 +++++++ .../main/java/com/google/protobuf/jruby/RubyMessage.java | 14 +++++++++++++- ruby/tests/basic.rb | 4 ++-- 3 files changed, 22 insertions(+), 3 deletions(-) (limited to 'ruby') 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=>[] -- cgit v1.2.3