package main import "base:runtime" import "core:reflect" import "core:strings" get_subtag :: proc(tag: string, id: string) -> (value: string, ok: bool) { parts := strings.split(tag, ",", context.temp_allocator) for part in parts { trimmed := strings.trim_space(part) if strings.has_prefix(trimmed, id) && len(trimmed) > len(id) && trimmed[len(id)] == '=' { return trimmed[len(id) + 1:], true } if trimmed == id { return "", true } } return "", false } is_bool_type :: proc(field: reflect.Struct_Field) -> bool { base_ti := runtime.type_info_base(field.type) _, is_bool := base_ti.variant.(runtime.Type_Info_Boolean) return is_bool } set_field :: proc(model: rawptr, field: reflect.Struct_Field, value: string) -> bool { ptr := rawptr(uintptr(model) + field.offset) base_ti := runtime.type_info_base(field.type) if _, is_bool := base_ti.variant.(runtime.Type_Info_Boolean); is_bool { (cast(^bool)ptr)^ = true return true } if _, is_string := base_ti.variant.(runtime.Type_Info_String); is_string { (cast(^string)ptr)^ = value return true } if enum_ti, is_enum := base_ti.variant.(runtime.Type_Info_Enum); is_enum { for name, i in enum_ti.names { if strings.equal_fold(value, name) { v := enum_ti.values[i] switch base_ti.size { case 1: (cast(^u8)ptr)^ = cast(u8)v case 2: (cast(^u16)ptr)^ = cast(u16)v case 4: (cast(^u32)ptr)^ = cast(u32)v case 8: (cast(^u64)ptr)^ = cast(u64)v } return true } } } return false } parse_flags :: proc(model: ^$T, args: []string) -> (overflow: []string) { field_count := reflect.struct_field_count(T) long_map := make(map[string]reflect.Struct_Field, field_count, context.temp_allocator) short_map := make(map[string]reflect.Struct_Field, field_count, context.temp_allocator) for i in 0..