VALUE build_module_from_enumdesc(EnumDescriptor* enumdesc) { VALUE mod = rb_define_module_id( rb_intern(upb_enumdef_fullname(enumdesc->enumdef))); upb_enum_iter it; for (upb_enum_begin(&it, enumdesc->enumdef); !upb_enum_done(&it); upb_enum_next(&it)) { const char* name = upb_enum_iter_name(&it); int32_t value = upb_enum_iter_number(&it); if (name[0] < 'A' || name[0] > 'Z') { rb_raise(rb_eTypeError, "Enum value '%s' does not start with an uppercase letter " "as is required for Ruby constants.", name); } rb_define_const(mod, name, INT2NUM(value)); } rb_define_singleton_method(mod, "lookup", enum_lookup, 1); rb_define_singleton_method(mod, "resolve", enum_resolve, 1); rb_define_singleton_method(mod, "descriptor", enum_descriptor, 0); rb_iv_set(mod, kDescriptorInstanceVar, get_def_obj(enumdesc->enumdef)); return mod; }
upb_enumdef *upb_enumdef_dup(const upb_enumdef *e) { upb_enumdef *new_e = upb_enumdef_new(); upb_enum_iter i; for(i = upb_enum_begin(e); !upb_enum_done(i); i = upb_enum_next(e, i)) { assert(upb_enumdef_addval(new_e, upb_enum_iter_name(i), upb_enum_iter_number(i))); } return new_e; }
upb_enumdef *upb_enumdef_dup(const upb_enumdef *e, const void *owner) { upb_enumdef *new_e = upb_enumdef_new(owner); if (!new_e) return NULL; upb_enum_iter i; for(upb_enum_begin(&i, e); !upb_enum_done(&i); upb_enum_next(&i)) { bool success = upb_enumdef_addval( new_e, upb_enum_iter_name(&i),upb_enum_iter_number(&i), NULL); if (!success) { upb_enumdef_unref(new_e, owner); return NULL; } } return new_e; }
/* * call-seq: * EnumDescriptor.each(&block) * * Iterates over key => value mappings in this enum's definition, yielding to * the block with (key, value) arguments for each one. */ VALUE EnumDescriptor_each(VALUE _self) { DEFINE_SELF(EnumDescriptor, self, _self); upb_enum_iter it; for (upb_enum_begin(&it, self->enumdef); !upb_enum_done(&it); upb_enum_next(&it)) { VALUE key = ID2SYM(rb_intern(upb_enum_iter_name(&it))); VALUE number = INT2NUM(upb_enum_iter_number(&it)); rb_yield_values(2, key, number); } return Qnil; }