|
@@ -139,6 +139,56 @@ assign_float :: proc(val: any, i: $T) -> bool {
|
|
|
}
|
|
|
|
|
|
|
|
|
+@(private)
|
|
|
+unmarsal_string :: proc(p: ^Parser, val: any, str: string, ti: ^reflect.Type_Info) -> bool {
|
|
|
+ val := val
|
|
|
+ switch dst in &val {
|
|
|
+ case string:
|
|
|
+ dst = str
|
|
|
+ return true
|
|
|
+ case cstring:
|
|
|
+ if str == "" {
|
|
|
+ dst = strings.clone_to_cstring("", p.allocator)
|
|
|
+ } else {
|
|
|
+ // NOTE: This is valid because 'clone_string' appends a NUL terminator
|
|
|
+ dst = cstring(raw_data(str))
|
|
|
+ }
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ defer delete(str, p.allocator)
|
|
|
+
|
|
|
+ #partial switch variant in ti.variant {
|
|
|
+ case reflect.Type_Info_Enum:
|
|
|
+ for name, i in variant.names {
|
|
|
+ if name == str {
|
|
|
+ assign_int(val, variant.values[i])
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // TODO(bill): should this be an error or not?
|
|
|
+ return true
|
|
|
+
|
|
|
+ case reflect.Type_Info_Integer:
|
|
|
+ i := strconv.parse_i128(str) or_return
|
|
|
+ if assign_int(val, i) {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ if assign_float(val, i) {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ case reflect.Type_Info_Float:
|
|
|
+ f := strconv.parse_f64(str) or_return
|
|
|
+ if assign_int(val, f) {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ if assign_float(val, f) {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return false
|
|
|
+}
|
|
|
+
|
|
|
|
|
|
@(private)
|
|
|
unmarsal_value :: proc(p: ^Parser, v: any) -> (err: Unmarshal_Error) {
|
|
@@ -195,60 +245,22 @@ unmarsal_value :: proc(p: ^Parser, v: any) -> (err: Unmarshal_Error) {
|
|
|
}
|
|
|
}
|
|
|
return UNSUPPORTED_TYPE
|
|
|
- case .String:
|
|
|
+
|
|
|
+ case .Ident:
|
|
|
advance_token(p)
|
|
|
- str := unquote_string(token, p.spec, p.allocator) or_return
|
|
|
- val := any{v.data, ti.id}
|
|
|
- switch dst in &val {
|
|
|
- case string:
|
|
|
- dst = str
|
|
|
- return
|
|
|
- case cstring:
|
|
|
- if str == "" {
|
|
|
- dst = strings.clone_to_cstring("", p.allocator)
|
|
|
- } else {
|
|
|
- // NOTE: This is valid because 'clone_string' appends a NUL terminator
|
|
|
- dst = cstring(raw_data(str))
|
|
|
+ if p.spec == .MJSON {
|
|
|
+ if unmarsal_string(p, any{v.data, ti.id}, token.text, ti) {
|
|
|
+ return nil
|
|
|
}
|
|
|
- return
|
|
|
}
|
|
|
- defer delete(str, p.allocator)
|
|
|
+ return UNSUPPORTED_TYPE
|
|
|
|
|
|
- #partial switch variant in ti.variant {
|
|
|
- case reflect.Type_Info_Enum:
|
|
|
- for name, i in variant.names {
|
|
|
- if name == str {
|
|
|
- assign_int(val, variant.values[i])
|
|
|
- return nil
|
|
|
- }
|
|
|
- }
|
|
|
- // TODO(bill): should this be an error or not?
|
|
|
+ case .String:
|
|
|
+ advance_token(p)
|
|
|
+ str := unquote_string(token, p.spec, p.allocator) or_return
|
|
|
+ if unmarsal_string(p, any{v.data, ti.id}, str, ti) {
|
|
|
return nil
|
|
|
-
|
|
|
- case reflect.Type_Info_Integer:
|
|
|
- i, ok := strconv.parse_i128(token.text)
|
|
|
- if !ok {
|
|
|
- return UNSUPPORTED_TYPE
|
|
|
- }
|
|
|
- if assign_int(val, i) {
|
|
|
- return
|
|
|
- }
|
|
|
- if assign_float(val, i) {
|
|
|
- return
|
|
|
- }
|
|
|
- case reflect.Type_Info_Float:
|
|
|
- f, ok := strconv.parse_f64(token.text)
|
|
|
- if !ok {
|
|
|
- return UNSUPPORTED_TYPE
|
|
|
- }
|
|
|
- if assign_int(val, f) {
|
|
|
- return
|
|
|
- }
|
|
|
- if assign_float(val, f) {
|
|
|
- return
|
|
|
- }
|
|
|
}
|
|
|
-
|
|
|
return UNSUPPORTED_TYPE
|
|
|
|
|
|
|