Ruby: fixed Message#to_h for map fields.
This commit is contained in:
parent
43f2db776c
commit
9c6b8cb9bf
@ -652,6 +652,35 @@ VALUE Map_hash(VALUE _self) {
|
||||
return INT2FIX(h);
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* Map.to_h => {}
|
||||
*
|
||||
* Returns a Ruby Hash object containing all the values within the map
|
||||
*/
|
||||
VALUE Map_to_h(VALUE _self) {
|
||||
Map* self = ruby_to_Map(_self);
|
||||
VALUE hash = rb_hash_new();
|
||||
upb_strtable_iter it;
|
||||
for (upb_strtable_begin(&it, &self->table);
|
||||
!upb_strtable_done(&it);
|
||||
upb_strtable_next(&it)) {
|
||||
VALUE key = table_key_to_ruby(
|
||||
self, upb_strtable_iter_key(&it), upb_strtable_iter_keylength(&it));
|
||||
upb_value v = upb_strtable_iter_value(&it);
|
||||
void* mem = value_memory(&v);
|
||||
VALUE value = native_slot_get(self->value_type,
|
||||
self->value_type_class,
|
||||
mem);
|
||||
|
||||
if (self->value_type == UPB_TYPE_MESSAGE) {
|
||||
value = Message_to_h(value);
|
||||
}
|
||||
rb_hash_aset(hash, key, value);
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* Map.inspect => string
|
||||
@ -804,6 +833,8 @@ void Map_register(VALUE module) {
|
||||
rb_define_method(klass, "dup", Map_dup, 0);
|
||||
rb_define_method(klass, "==", Map_eq, 1);
|
||||
rb_define_method(klass, "hash", Map_hash, 0);
|
||||
rb_define_method(klass, "to_hash", Map_to_h, 0);
|
||||
rb_define_method(klass, "to_h", Map_to_h, 0);
|
||||
rb_define_method(klass, "inspect", Map_inspect, 0);
|
||||
rb_define_method(klass, "merge", Map_merge, 1);
|
||||
rb_include_module(klass, rb_mEnumerable);
|
||||
|
@ -394,7 +394,12 @@ VALUE Message_inspect(VALUE _self) {
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* Message.to_h => {}
|
||||
*
|
||||
* Returns the message as a Ruby Hash object, with keys as symbols.
|
||||
*/
|
||||
VALUE Message_to_h(VALUE _self) {
|
||||
MessageHeader* self;
|
||||
VALUE hash;
|
||||
@ -410,8 +415,13 @@ VALUE Message_to_h(VALUE _self) {
|
||||
VALUE msg_value = layout_get(self->descriptor->layout, Message_data(self),
|
||||
field);
|
||||
VALUE msg_key = ID2SYM(rb_intern(upb_fielddef_name(field)));
|
||||
if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
|
||||
if (upb_fielddef_ismap(field)) {
|
||||
msg_value = Map_to_h(msg_value);
|
||||
} else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
|
||||
msg_value = RepeatedField_to_ary(msg_value);
|
||||
} else if (msg_value != Qnil &&
|
||||
upb_fielddef_type(field) == UPB_TYPE_MESSAGE) {
|
||||
msg_value = Message_to_h(msg_value);
|
||||
}
|
||||
rb_hash_aset(hash, msg_key, msg_value);
|
||||
}
|
||||
|
@ -424,6 +424,7 @@ VALUE Map_dup(VALUE _self);
|
||||
VALUE Map_deep_copy(VALUE _self);
|
||||
VALUE Map_eq(VALUE _self, VALUE _other);
|
||||
VALUE Map_hash(VALUE _self);
|
||||
VALUE Map_to_h(VALUE _self);
|
||||
VALUE Map_inspect(VALUE _self);
|
||||
VALUE Map_merge(VALUE _self, VALUE hashmap);
|
||||
VALUE Map_merge_into_self(VALUE _self, VALUE hashmap);
|
||||
@ -496,6 +497,7 @@ VALUE Message_deep_copy(VALUE _self);
|
||||
VALUE Message_eq(VALUE _self, VALUE _other);
|
||||
VALUE Message_hash(VALUE _self);
|
||||
VALUE Message_inspect(VALUE _self);
|
||||
VALUE Message_to_h(VALUE _self);
|
||||
VALUE Message_index(VALUE _self, VALUE field_name);
|
||||
VALUE Message_index_set(VALUE _self, VALUE field_name, VALUE value);
|
||||
VALUE Message_descriptor(VALUE klass);
|
||||
|
@ -927,6 +927,16 @@ module BasicTest
|
||||
:repeated_uint64=>[]
|
||||
}
|
||||
assert_equal expected_result, m.to_h
|
||||
|
||||
m = MapMessage.new(
|
||||
:map_string_int32 => {"a" => 1, "b" => 2},
|
||||
:map_string_msg => {"a" => TestMessage2.new(:foo => 1),
|
||||
"b" => TestMessage2.new(:foo => 2)})
|
||||
expected_result = {
|
||||
:map_string_int32=>{"a"=>1, "b"=>2},
|
||||
:map_string_msg=>{"a"=>{:foo=>1}, "b"=>{:foo=>2}}
|
||||
}
|
||||
assert_equal expected_result, m.to_h
|
||||
end
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user