[Ruby] allow encode json options to be an object that responds to to_hash (#9513)

* allow encode json options to be an object that responds to to_hash

fixes #9500

* try to convert options arg to hash if it is not a hash
pull/9588/head
Luka Dornhecker 3 years ago committed by GitHub
parent 92cdf87f1a
commit 24a0659f95
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      ruby/ext/google/protobuf_c/message.c
  2. 10
      ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java
  3. 3
      ruby/tests/common_tests.rb

@ -1141,8 +1141,12 @@ static VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass) {
if (argc == 2) { if (argc == 2) {
VALUE hash_args = argv[1]; VALUE hash_args = argv[1];
if (TYPE(hash_args) != T_HASH) { if (TYPE(hash_args) != T_HASH) {
if (RTEST(rb_funcall(hash_args, rb_intern("respond_to?"), 1, rb_str_new2("to_h")))) {
hash_args = rb_funcall(hash_args, rb_intern("to_h"), 0);
} else {
rb_raise(rb_eArgError, "Expected hash arguments."); rb_raise(rb_eArgError, "Expected hash arguments.");
} }
}
if (RTEST(rb_hash_lookup2(hash_args, if (RTEST(rb_hash_lookup2(hash_args,
ID2SYM(rb_intern("preserve_proto_fieldnames")), ID2SYM(rb_intern("preserve_proto_fieldnames")),

@ -555,7 +555,15 @@ public class RubyMessage extends RubyObject {
String result; String result;
if (args.length > 1) { if (args.length > 1) {
RubyHash options = (RubyHash) args[1]; RubyHash options;
if (args[1] instanceof RubyHash) {
options = (RubyHash) args[1];
} else if (args[1].respondsTo("to_h")) {
options = (RubyHash) args[1].callMethod(context, "to_h");
} else {
throw runtime.newArgumentError("Expected hash arguments.");
}
IRubyObject emitDefaults = options.fastARef(runtime.newSymbol("emit_defaults")); IRubyObject emitDefaults = options.fastARef(runtime.newSymbol("emit_defaults"));
IRubyObject preserveNames = options.fastARef(runtime.newSymbol("preserve_proto_fieldnames")); IRubyObject preserveNames = options.fastARef(runtime.newSymbol("preserve_proto_fieldnames"));

@ -870,6 +870,9 @@ module CommonTests
decoded_msg = Google::Protobuf.decode_json(proto_module::TestMessage, encoded_msg) decoded_msg = Google::Protobuf.decode_json(proto_module::TestMessage, encoded_msg)
assert_equal proto_module::TestMessage.decode_json(m.to_json), decoded_msg assert_equal proto_module::TestMessage.decode_json(m.to_json), decoded_msg
assert_equal [m].to_json, Google::Protobuf.encode_json([m])
assert_equal proto_module::TestMessage.decode_json([m.to_json].first), decoded_msg
end end
def test_def_errors def test_def_errors

Loading…
Cancel
Save