Add decoding of map
This commit is contained in:
91
decode.odin
91
decode.odin
@@ -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:
|
||||||
newkey, err := strings.split_after_n(key, ".", 2)
|
return decode(any{v.data, ti.id}, key)
|
||||||
|
|
||||||
if len(newkey) != 2 || err != nil {
|
case runtime.Type_Info_Union:
|
||||||
return decode( reflect.struct_field_value_by_name(v, key), "." )
|
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] )
|
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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user