package server import "core:encoding/json" import "core:strings" import "core:runtime" import "core:mem" import "core:fmt" /* Right now union handling is type specific so you can only have one struct type, int type, etc. */ unmarshal :: proc(json_value: json.Value, v: any, allocator: mem.Allocator) -> json.Marshal_Error { using runtime if v == nil { return nil } if json_value == nil { return nil } type_info := type_info_base(type_info_of(v.id)) #partial switch j in json_value { case json.Object: #partial switch variant in type_info.variant { case Type_Info_Struct: for field, i in variant.names { a := any {rawptr(uintptr(v.data) + uintptr(variant.offsets[i])), variant.types[i].id} //TEMP most likely have to rewrite the entire unmarshal using tags instead, because i sometimes have to support names like 'context', which can't be written like that if field[len(field)-1] == '_' { if ret := unmarshal(j[field[:len(field)-1]], a, allocator); ret != nil { return ret } } else { if ret := unmarshal(j[field], a, allocator); ret != nil { return ret } } } case Type_Info_Union: //Note(Daniel, THIS IS REALLY SCUFFED. Need to talk to gingerbill about unmarshalling unions) //This only works for unions with one object - made to handle optionals tag_ptr := uintptr(v.data) + variant.tag_offset tag_any := any {rawptr(tag_ptr), variant.tag_type.id} not_optional := 1 mem.copy(cast(rawptr)tag_ptr, ¬_optional, size_of(variant.tag_type)) id := variant.variants[0].id unmarshal(json_value, any {v.data, id}, allocator) } case json.Array: #partial switch variant in type_info.variant { case Type_Info_Dynamic_Array: array := (^mem.Raw_Dynamic_Array)(v.data) if array.data == nil { array.data = mem.alloc(len(j) * variant.elem_size, variant.elem.align, allocator) array.len = len(j) array.cap = len(j) array.allocator = allocator } else { return .Unsupported_Type } for i in 0..