Skip to content

Commit

Permalink
feat(6178): emit ruby enum as integer (#11673)
Browse files Browse the repository at this point in the history
Fixes #6178

- Add a new option `enums_as_integers` to emit enum as integer value.

Closes #11673

COPYBARA_INTEGRATE_REVIEW=#11673 from MQuy:feat/6178-ruby-enum-as-integer 90f986a
PiperOrigin-RevId: 514789180
  • Loading branch information
MQuy authored and Copybara-Service committed Mar 7, 2023
1 parent 818129a commit 8aa2b17
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 0 deletions.
6 changes: 6 additions & 0 deletions ruby/ext/google/protobuf_c/message.c
Expand Up @@ -1164,6 +1164,12 @@ static VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass) {
Qfalse))) {
options |= upb_JsonEncode_EmitDefaults;
}

if (RTEST(rb_hash_lookup2(hash_args,
ID2SYM(rb_intern("format_enums_as_integers")),
Qfalse))) {
options |= upb_JsonEncode_FormatEnumsAsIntegers;
}
}

upb_Status_Clear(&status);
Expand Down
7 changes: 7 additions & 0 deletions ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java
Expand Up @@ -669,6 +669,7 @@ public static IRubyObject decode(ThreadContext context, IRubyObject recv, IRubyO
* @param options [Hash] options for the decoder
* preserve_proto_fieldnames: set true to use original fieldnames (default is to camelCase)
* emit_defaults: set true to emit 0/false values (default is to omit them)
* format_enums_as_integers: set true to emit enum values as integer (default is string)
*/
@JRubyMethod(name = "encode_json", required = 1, optional = 1, meta = true)
public static IRubyObject encodeJson(
Expand All @@ -690,6 +691,8 @@ public static IRubyObject encodeJson(

IRubyObject emitDefaults = options.fastARef(runtime.newSymbol("emit_defaults"));
IRubyObject preserveNames = options.fastARef(runtime.newSymbol("preserve_proto_fieldnames"));
IRubyObject printingEnumsAsInts =
options.fastARef(runtime.newSymbol("format_enums_as_integers"));

if (emitDefaults != null && emitDefaults.isTrue()) {
printer = printer.includingDefaultValueFields();
Expand All @@ -698,6 +701,10 @@ public static IRubyObject encodeJson(
if (preserveNames != null && preserveNames.isTrue()) {
printer = printer.preservingProtoFieldNames();
}

if (printingEnumsAsInts != null && printingEnumsAsInts.isTrue()) {
printer = printer.printingEnumsAsInts();
}
}
printer =
printer.usingTypeRegistry(
Expand Down
28 changes: 28 additions & 0 deletions ruby/tests/encode_decode_test.rb
Expand Up @@ -84,6 +84,34 @@ def test_encode_json
)

assert_match 'optional_int32', json


# Test for enums printing as ints.
msg = A::B::C::TestMessage.new({ optional_enum: 1 })
json = A::B::C::TestMessage.encode_json(
msg,
{ :format_enums_as_integers => true }
)

assert_match '"optionalEnum":1', json

# Test for default enum being printed as int.
msg = A::B::C::TestMessage.new({ optional_enum: 0 })
json = A::B::C::TestMessage.encode_json(
msg,
{ :format_enums_as_integers => true, :emit_defaults => true }
)

assert_match '"optionalEnum":0', json

# Test for repeated enums printing as ints.
msg = A::B::C::TestMessage.new({ repeated_enum: [0,1,2,3] })
json = A::B::C::TestMessage.encode_json(
msg,
{ :format_enums_as_integers => true }
)

assert_match '"repeatedEnum":[0,1,2,3]', json
end

def test_encode_wrong_msg
Expand Down

0 comments on commit 8aa2b17

Please sign in to comment.