diff --git a/decode.odin b/decode.odin index c9d6bf3..201047a 100644 --- a/decode.odin +++ b/decode.odin @@ -1,38 +1,82 @@ package mustache +import "base:runtime" +import "core:mem" + import "core:reflect" import "core:strings" import "core:log" import "core:fmt" decode :: proc( v: any, key: string ) -> any { - if v == nil do return "" + if key == "." do return v v := reflect.any_base(v) ti := type_info_of(v.id) - switch { - case reflect.is_struct(ti): - newkey, err := strings.split_after_n(key, ".", 2) + #partial switch i in runtime.type_info_base(ti).variant { + case runtime.Type_Info_Enumerated_Array: + return decode(any{v.data, ti.id}, key) - if len(newkey) != 2 || err != nil { - return decode( reflect.struct_field_value_by_name(v, key), "." ) + case runtime.Type_Info_Union: + return decode(any{v.data, reflect.union_variant_typeid(v) }, key) + + case runtime.Type_Info_Struct: + newkey, err := strings.split_after_n(key, ".", 2) + + if err != nil { + return nil } - return decode( reflect.struct_field_value_by_name(v, newkey[0][:len(newkey[0])-1]), newkey[1] ) - case reflect.is_string(ti): - if key != "." do return "" - return v - case reflect.is_integer(ti): - if key != "." do return "" - return v - case reflect.is_enum(ti): - return decode(any{v.data, ti.id}, key) - case reflect.is_slice(ti): - if key != "." do return "" - return v - case: - log.warnf("%v", ti) + defer delete(newkey) + + newkey_0 := newkey[0] + newkey_1 := "." + + if len(newkey) == 2 { + newkey_0 = newkey[0][:len(newkey[0])-1] + newkey_1 = newkey[1] + } + + return decode( reflect.struct_field_value_by_name(v, newkey_0), newkey_1 ) + + + case runtime.Type_Info_Map: + newkey, err := strings.split_after_n(key, ".", 2) + + if err!= nil { + return nil + } + + defer delete(newkey) + + newkey_0 := newkey[0] + newkey_1 := "." + + if len(newkey) == 2 { + newkey_0 = newkey[0][:len(newkey[0])-1] + newkey_1 = newkey[1] + } + + + m := (^mem.Raw_Map)(v.data) + ks, vs, _, _, _ := runtime.map_kvh_data_dynamic(m^, i.map_info) + + for j in 0.. string { t := reflect.any_base(decode(v, key)) ti := type_info_of(t.id) - ret : string - switch { - case reflect.is_slice(ti): + ret : string= "" + #partial switch i in runtime.type_info_base(ti).variant { + case runtime.Type_Info_Slice: for i in 0.. string { defer delete(tmp) ret = strings.concatenate({ret, tmp}) - log.infof(ret) } }