Commit 3bdaaa5d authored by Marcin Wyszynski's avatar Marcin Wyszynski

More Ruby-eqsue interface

parent 93a4fa23
......@@ -178,6 +178,45 @@ VALUE Message_method_missing(int argc, VALUE* argv, VALUE _self) {
}
}
VALUE Message_respond_to_missing(int argc, VALUE* argv, VALUE _self) {
MessageHeader* self;
VALUE method_name, method_str;
char* name;
size_t name_len;
bool setter;
const upb_oneofdef* o;
const upb_fielddef* f;
TypedData_Get_Struct(_self, MessageHeader, &Message_type, self);
if (argc < 1) {
rb_raise(rb_eArgError, "Expected method name as first argument.");
}
method_name = argv[0];
if (!SYMBOL_P(method_name)) {
rb_raise(rb_eArgError, "Expected symbol as method name.");
}
method_str = rb_id2str(SYM2ID(method_name));
name = RSTRING_PTR(method_str);
name_len = RSTRING_LEN(method_str);
setter = false;
// Setters have names that end in '='.
if (name[name_len - 1] == '=') {
setter = true;
name_len--;
}
// See if this name corresponds to either a oneof or field in this message.
if (!upb_msgdef_lookupname(self->descriptor->msgdef, name, name_len, &f,
&o)) {
return rb_call_super(argc, argv);
}
if (o != NULL) {
return setter ? Qfalse : Qtrue;
}
return Qtrue;
}
int Message_initialize_kwarg(VALUE key, VALUE val, VALUE _self) {
MessageHeader* self;
VALUE method_str;
......@@ -303,6 +342,9 @@ VALUE Message_deep_copy(VALUE _self) {
* field is of a primitive type).
*/
VALUE Message_eq(VALUE _self, VALUE _other) {
if (TYPE(_self) != TYPE(_other)) {
return Qfalse;
}
MessageHeader* self;
MessageHeader* other;
TypedData_Get_Struct(_self, MessageHeader, &Message_type, self);
......@@ -459,6 +501,8 @@ VALUE build_class_from_descriptor(Descriptor* desc) {
rb_define_method(klass, "method_missing",
Message_method_missing, -1);
rb_define_method(klass, "respond_to_missing?",
Message_respond_to_missing, -1);
rb_define_method(klass, "initialize", Message_initialize, -1);
rb_define_method(klass, "dup", Message_dup, 0);
// Also define #clone so that we don't inherit Object#clone.
......
......@@ -1181,5 +1181,15 @@ module BasicTest
m2 = MapMessage.decode_json(MapMessage.encode_json(m))
assert m == m2
end
def test_comparison_with_arbitrary_object
assert_false MapMessage.new == nil
end
def test_respond_to
msg = MapMessage.new
assert msg.respond_to?(:map_string_int32)
assert_false msg.respond_to?(:map_string_int32)
end
end
end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment