Ruby oneofs: return default instead of nil for unset fields.
This commit is contained in:
parent
32e3d7a109
commit
545527e8cf
@ -57,6 +57,28 @@ size_t native_slot_size(upb_fieldtype_t type) {
|
||||
}
|
||||
}
|
||||
|
||||
VALUE value_from_default(const upb_fielddef *field) {
|
||||
switch (upb_fielddef_type(field)) {
|
||||
case UPB_TYPE_FLOAT: return DBL2NUM(upb_fielddef_defaultfloat(field));
|
||||
case UPB_TYPE_DOUBLE: return DBL2NUM(upb_fielddef_defaultdouble(field));
|
||||
case UPB_TYPE_BOOL:
|
||||
return upb_fielddef_defaultbool(field) ? Qtrue : Qfalse;
|
||||
case UPB_TYPE_MESSAGE: return Qnil;
|
||||
case UPB_TYPE_ENUM: return INT2NUM(upb_fielddef_defaultint32(field));
|
||||
case UPB_TYPE_INT32: return INT2NUM(upb_fielddef_defaultint32(field));
|
||||
case UPB_TYPE_INT64: return LL2NUM(upb_fielddef_defaultint64(field));;
|
||||
case UPB_TYPE_UINT32: return UINT2NUM(upb_fielddef_defaultuint32(field));
|
||||
case UPB_TYPE_UINT64: return ULL2NUM(upb_fielddef_defaultuint64(field));
|
||||
case UPB_TYPE_STRING:
|
||||
case UPB_TYPE_BYTES: {
|
||||
size_t size;
|
||||
const char *str = upb_fielddef_defaultstr(field, &size);
|
||||
return rb_str_new(str, size);
|
||||
}
|
||||
default: return Qnil;
|
||||
}
|
||||
}
|
||||
|
||||
static bool is_ruby_num(VALUE value) {
|
||||
return (TYPE(value) == T_FLOAT ||
|
||||
TYPE(value) == T_FIXNUM ||
|
||||
@ -537,7 +559,7 @@ VALUE layout_get(MessageLayout* layout,
|
||||
|
||||
if (upb_fielddef_containingoneof(field)) {
|
||||
if (*oneof_case != upb_fielddef_number(field)) {
|
||||
return Qnil;
|
||||
return value_from_default(field);
|
||||
}
|
||||
return native_slot_get(upb_fielddef_type(field),
|
||||
field_type_class(field),
|
||||
|
@ -703,36 +703,36 @@ module BasicTest
|
||||
|
||||
def test_oneof
|
||||
d = OneofMessage.new
|
||||
assert d.a == nil
|
||||
assert d.b == nil
|
||||
assert d.a == ""
|
||||
assert d.b == 0
|
||||
assert d.c == nil
|
||||
assert d.d == nil
|
||||
assert d.d == 0
|
||||
assert d.my_oneof == nil
|
||||
|
||||
d.a = "hi"
|
||||
assert d.a == "hi"
|
||||
assert d.b == nil
|
||||
assert d.b == 0
|
||||
assert d.c == nil
|
||||
assert d.d == nil
|
||||
assert d.d == 0
|
||||
assert d.my_oneof == :a
|
||||
|
||||
d.b = 42
|
||||
assert d.a == nil
|
||||
assert d.a == ""
|
||||
assert d.b == 42
|
||||
assert d.c == nil
|
||||
assert d.d == nil
|
||||
assert d.d == 0
|
||||
assert d.my_oneof == :b
|
||||
|
||||
d.c = TestMessage2.new(:foo => 100)
|
||||
assert d.a == nil
|
||||
assert d.b == nil
|
||||
assert d.a == ""
|
||||
assert d.b == 0
|
||||
assert d.c.foo == 100
|
||||
assert d.d == nil
|
||||
assert d.d == 0
|
||||
assert d.my_oneof == :c
|
||||
|
||||
d.d = :C
|
||||
assert d.a == nil
|
||||
assert d.b == nil
|
||||
assert d.a == ""
|
||||
assert d.b == 0
|
||||
assert d.c == nil
|
||||
assert d.d == :C
|
||||
assert d.my_oneof == :d
|
||||
@ -748,23 +748,23 @@ module BasicTest
|
||||
|
||||
d3 = OneofMessage.decode(
|
||||
encoded_field_c + encoded_field_a + encoded_field_d)
|
||||
assert d3.a == nil
|
||||
assert d3.b == nil
|
||||
assert d3.a == ""
|
||||
assert d3.b == 0
|
||||
assert d3.c == nil
|
||||
assert d3.d == :B
|
||||
|
||||
d4 = OneofMessage.decode(
|
||||
encoded_field_c + encoded_field_a + encoded_field_d +
|
||||
encoded_field_c)
|
||||
assert d4.a == nil
|
||||
assert d4.b == nil
|
||||
assert d4.a == ""
|
||||
assert d4.b == 0
|
||||
assert d4.c.foo == 1
|
||||
assert d4.d == nil
|
||||
assert d4.d == 0
|
||||
|
||||
d5 = OneofMessage.new(:a => "hello")
|
||||
assert d5.a != nil
|
||||
assert d5.a == "hello"
|
||||
d5.a = nil
|
||||
assert d5.a == nil
|
||||
assert d5.a == ""
|
||||
assert OneofMessage.encode(d5) == ''
|
||||
assert d5.my_oneof == nil
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user