diff options
author | Chris Fallin <cfallin@c1f.net> | 2015-05-02 19:02:08 -0700 |
---|---|---|
committer | Chris Fallin <cfallin@c1f.net> | 2015-05-02 19:02:08 -0700 |
commit | 16a283f7942be34eb47852832131dfef2d196f83 (patch) | |
tree | d99562c8fc9052afd1aced0aa9709a25637bdc7c | |
parent | dcf12136835af5239f0877aa455eabbd7b88b61e (diff) | |
parent | 64678265c5ae28998d031900c2de52419a8ed7e4 (diff) | |
download | protobuf-16a283f7942be34eb47852832131dfef2d196f83.tar.gz protobuf-16a283f7942be34eb47852832131dfef2d196f83.tar.bz2 protobuf-16a283f7942be34eb47852832131dfef2d196f83.zip |
Merge pull request #334 from skippy/allow-msg-to-accept-nil
ruby: allow a message field to be unset
-rw-r--r-- | ruby/ext/google/protobuf_c/storage.c | 4 | ||||
-rw-r--r-- | ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java | 15 | ||||
-rw-r--r-- | ruby/tests/basic.rb | 2 |
3 files changed, 15 insertions, 6 deletions
diff --git a/ruby/ext/google/protobuf_c/storage.c b/ruby/ext/google/protobuf_c/storage.c index 5b1549d2..2ad8bd74 100644 --- a/ruby/ext/google/protobuf_c/storage.c +++ b/ruby/ext/google/protobuf_c/storage.c @@ -155,7 +155,9 @@ void native_slot_set_value_and_case(upb_fieldtype_t type, VALUE type_class, break; } case UPB_TYPE_MESSAGE: { - if (CLASS_OF(value) != type_class) { + if (CLASS_OF(value) == CLASS_OF(Qnil)) { + value = Qnil; + } else if (CLASS_OF(value) != type_class) { rb_raise(rb_eTypeError, "Invalid type %s to assign to submessage field.", rb_class2name(CLASS_OF(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 20e825e2..c7fd7aa7 100644 --- a/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java +++ b/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java @@ -659,14 +659,14 @@ public class RubyMessage extends RubyObject { } else { Descriptors.FieldDescriptor.Type fieldType = fieldDescriptor.getType(); IRubyObject typeClass = context.runtime.getObject(); + boolean addValue = true; if (fieldType == Descriptors.FieldDescriptor.Type.MESSAGE) { typeClass = ((RubyDescriptor) getDescriptorForField(context, fieldDescriptor)).msgclass(context); + if (value.isNil()){ + addValue = false; + } } else if (fieldType == Descriptors.FieldDescriptor.Type.ENUM) { typeClass = ((RubyEnumDescriptor) getDescriptorForField(context, fieldDescriptor)).enummodule(context); - } - Utils.checkType(context, fieldType, value, (RubyModule) typeClass); - // Convert integer enum to symbol - if (fieldType == Descriptors.FieldDescriptor.Type.ENUM) { Descriptors.EnumDescriptor enumDescriptor = fieldDescriptor.getEnumType(); if (Utils.isRubyNum(value)) { Descriptors.EnumValueDescriptor val = @@ -674,7 +674,12 @@ public class RubyMessage extends RubyObject { if (val.getIndex() != -1) value = context.runtime.newSymbol(val.getName()); } } - this.fields.put(fieldDescriptor, value); + if (addValue) { + Utils.checkType(context, fieldType, value, (RubyModule) typeClass); + this.fields.put(fieldDescriptor, value); + } else { + this.fields.remove(fieldDescriptor); + } } } return context.runtime.getNil(); diff --git a/ruby/tests/basic.rb b/ruby/tests/basic.rb index 141ce7c5..1c2a03dc 100644 --- a/ruby/tests/basic.rb +++ b/ruby/tests/basic.rb @@ -154,6 +154,8 @@ module BasicTest assert m.optional_bytes == "world" m.optional_msg = TestMessage2.new(:foo => 42) assert m.optional_msg == TestMessage2.new(:foo => 42) + m.optional_msg = nil + assert m.optional_msg == nil end def test_ctor_args |