From 8d2430e54d40bb705499f5cfeef9fead6d9ad833 Mon Sep 17 00:00:00 2001 From: Tetralux Date: Thu, 7 May 2020 00:32:35 +0000 Subject: [PATCH] Add reflect.enum_from_name Provides a way to go from a enum value name string to an actual enum value. ``` E :: enum { A, B } // ... s := "B"; v, ok := enum_from_name(E, s); assert(ok && v == E.B); ``` --- core/reflect/reflect.odin | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/core/reflect/reflect.odin b/core/reflect/reflect.odin index 12428d59c..f92dc1f39 100644 --- a/core/reflect/reflect.odin +++ b/core/reflect/reflect.odin @@ -510,6 +510,34 @@ enum_string :: proc(a: any) -> string { return ""; } +// Given a enum type and a value name, get the enum value. +enum_from_name :: proc($EnumType: typeid, name: string) -> (value: EnumType, ok: bool) { + ti := type_info_base(type_info_of(EnumType)); + if eti, eti_ok := ti.variant.(runtime.Type_Info_Enum); eti_ok { + for value_name, i in eti.names { + if value_name != name do continue; + value_union := eti.values[i]; + switch v in value_union { + case rune: value = EnumType(v); ok = true; + case u8: value = EnumType(v); ok = true; + case u16: value = EnumType(v); ok = true; + case u32: value = EnumType(v); ok = true; + case u64: value = EnumType(v); ok = true; + case uint: value = EnumType(v); ok = true; + case uintptr: value = EnumType(v); ok = true; + case i8: value = EnumType(v); ok = true; + case i16: value = EnumType(v); ok = true; + case i32: value = EnumType(v); ok = true; + case i64: value = EnumType(v); ok = true; + case int: value = EnumType(v); ok = true; + } + } + } else { + panic("expected enum type to reflect.enum_from_name"); + } + return; +} + union_variant_type_info :: proc(a: any) -> ^runtime.Type_Info { id := union_variant_typeid(a); return type_info_of(id);