Add decoding of map

This commit is contained in:
PedroEdiaz
2025-06-19 00:35:24 -06:00
parent 03292a15c8
commit f9f4f5d34a

View File

@@ -1,38 +1,82 @@
package mustache package mustache
import "base:runtime"
import "core:mem"
import "core:reflect" import "core:reflect"
import "core:strings" import "core:strings"
import "core:log" import "core:log"
import "core:fmt" import "core:fmt"
decode :: proc( v: any, key: string ) -> any { decode :: proc( v: any, key: string ) -> any {
if v == nil do return "" if key == "." do return v
v := reflect.any_base(v) v := reflect.any_base(v)
ti := type_info_of(v.id) ti := type_info_of(v.id)
switch { #partial switch i in runtime.type_info_base(ti).variant {
case reflect.is_struct(ti): case runtime.Type_Info_Enumerated_Array:
return decode(any{v.data, ti.id}, 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) newkey, err := strings.split_after_n(key, ".", 2)
if len(newkey) != 2 || err != nil { if err != nil {
return decode( reflect.struct_field_value_by_name(v, key), "." ) return nil
} }
return decode( reflect.struct_field_value_by_name(v, newkey[0][:len(newkey[0])-1]), newkey[1] ) defer delete(newkey)
case reflect.is_string(ti):
if key != "." do return "" newkey_0 := newkey[0]
return v newkey_1 := "."
case reflect.is_integer(ti):
if key != "." do return "" if len(newkey) == 2 {
return v newkey_0 = newkey[0][:len(newkey[0])-1]
case reflect.is_enum(ti): newkey_1 = newkey[1]
return decode(any{v.data, ti.id}, key) }
case reflect.is_slice(ti):
if key != "." do return "" return decode( reflect.struct_field_value_by_name(v, newkey_0), newkey_1 )
return v
case:
log.warnf("%v", ti) 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..<runtime.map_cap(m^) {
key_data := runtime.map_cell_index_dynamic(ks, i.map_info.ks, uintptr(j))
ky, ok := reflect.as_string(any{rawptr(key_data), i.key.id})
if !ok {
return nil
}
if ky == newkey_0 {
t := any{rawptr(runtime.map_cell_index_dynamic(vs, i.map_info.vs, uintptr(j))), i.value.id}
return decode(t, newkey_1 )
}
}
return ""
} }
return "" return ""
@@ -50,9 +94,9 @@ preprocess :: proc( r: ^strings.Reader, v: any, key: string ) -> string {
t := reflect.any_base(decode(v, key)) t := reflect.any_base(decode(v, key))
ti := type_info_of(t.id) ti := type_info_of(t.id)
ret : string ret : string= ""
switch { #partial switch i in runtime.type_info_base(ti).variant {
case reflect.is_slice(ti): case runtime.Type_Info_Slice:
for i in 0..<reflect.length(t) { for i in 0..<reflect.length(t) {
elem :=reflect.index(t, i); elem :=reflect.index(t, i);
@@ -61,7 +105,6 @@ preprocess :: proc( r: ^strings.Reader, v: any, key: string ) -> string {
defer delete(tmp) defer delete(tmp)
ret = strings.concatenate({ret, tmp}) ret = strings.concatenate({ret, tmp})
log.infof(ret)
} }
} }