json: decode/encode time.Time
							parent
							
								
									9eb6c4ef87
								
							
						
					
					
						commit
						b3e0926601
					
				| 
						 | 
					@ -1,4 +1,5 @@
 | 
				
			||||||
import json
 | 
					import json
 | 
				
			||||||
 | 
					import time
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum JobTitle {
 | 
					enum JobTitle {
 | 
				
			||||||
	manager
 | 
						manager
 | 
				
			||||||
| 
						 | 
					@ -33,9 +34,11 @@ fn bar<T>(payload string) ?Bar { // ?T doesn't work currently
 | 
				
			||||||
	result := json.decode(T, payload) ?
 | 
						result := json.decode(T, payload) ?
 | 
				
			||||||
	return result
 | 
						return result
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct Bar {
 | 
					struct Bar {
 | 
				
			||||||
	x string
 | 
						x string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn test_generic() {
 | 
					fn test_generic() {
 | 
				
			||||||
	result := bar<Bar>('{"x":"test"}') or { Bar{} }
 | 
						result := bar<Bar>('{"x":"test"}') or { Bar{} }
 | 
				
			||||||
	assert result.x == 'test'
 | 
						assert result.x == 'test'
 | 
				
			||||||
| 
						 | 
					@ -44,6 +47,7 @@ fn test_generic() {
 | 
				
			||||||
struct User2 {
 | 
					struct User2 {
 | 
				
			||||||
	age      int
 | 
						age      int
 | 
				
			||||||
	nums     []int
 | 
						nums     []int
 | 
				
			||||||
 | 
						reg_date time.Time
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct User {
 | 
					struct User {
 | 
				
			||||||
| 
						 | 
					@ -57,13 +61,9 @@ struct User {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn test_parse_user() {
 | 
					fn test_parse_user() {
 | 
				
			||||||
	s := '{"age": 10, "nums": [1,2,3], "type": 1, "lastName": "Johnson", "IsRegistered": true, "pet_animals": {"name": "Bob", "animal": "Dog"}}'
 | 
						s := '{"age": 10, "nums": [1,2,3], "type": 1, "lastName": "Johnson", "IsRegistered": true, "pet_animals": {"name": "Bob", "animal": "Dog"}}'
 | 
				
			||||||
	u2 := json.decode(User2, s) or {
 | 
						u2 := json.decode(User2, s) or { exit(1) }
 | 
				
			||||||
		exit(1)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	println(u2)
 | 
						println(u2)
 | 
				
			||||||
	u := json.decode(User, s) or {
 | 
						u := json.decode(User, s) or { exit(1) }
 | 
				
			||||||
		exit(1)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	println(u)
 | 
						println(u)
 | 
				
			||||||
	assert u.age == 10
 | 
						assert u.age == 10
 | 
				
			||||||
	assert u.last_name == 'Johnson'
 | 
						assert u.last_name == 'Johnson'
 | 
				
			||||||
| 
						 | 
					@ -76,6 +76,23 @@ fn test_parse_user() {
 | 
				
			||||||
	assert u.pets == '{"name":"Bob","animal":"Dog"}'
 | 
						assert u.pets == '{"name":"Bob","animal":"Dog"}'
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn test_encode_decode_time() {
 | 
				
			||||||
 | 
						user := User2{
 | 
				
			||||||
 | 
							age: 25
 | 
				
			||||||
 | 
							reg_date: time.new_time(year: 2020, month: 12, day: 22, hour: 7, minute: 23)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						s := json.encode(user)
 | 
				
			||||||
 | 
						println(s)
 | 
				
			||||||
 | 
						assert s.contains('"reg_date":1608621780')
 | 
				
			||||||
 | 
						user2 := json.decode(User2, s) or {
 | 
				
			||||||
 | 
							assert false
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						assert user2.reg_date.str() == '2020-12-22 07:23:00'
 | 
				
			||||||
 | 
						println(user2)
 | 
				
			||||||
 | 
						println(user2.reg_date)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn (mut u User) foo() string {
 | 
					fn (mut u User) foo() string {
 | 
				
			||||||
	return json.encode(u)
 | 
						return json.encode(u)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -268,9 +285,7 @@ fn test_generic_struct() {
 | 
				
			||||||
	foo_int := Foo<int>{'bar', 12}
 | 
						foo_int := Foo<int>{'bar', 12}
 | 
				
			||||||
	foo_enc := json.encode(foo_int)
 | 
						foo_enc := json.encode(foo_int)
 | 
				
			||||||
	assert foo_enc == '{"name":"bar","data":12}'
 | 
						assert foo_enc == '{"name":"bar","data":12}'
 | 
				
			||||||
	foo_dec := json.decode(Foo<int>, foo_enc) or {
 | 
						foo_dec := json.decode(Foo<int>, foo_enc) or { exit(1) }
 | 
				
			||||||
		exit(1)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	assert foo_dec.name == 'bar'
 | 
						assert foo_dec.name == 'bar'
 | 
				
			||||||
	assert foo_dec.data == 12
 | 
						assert foo_dec.data == 12
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -331,7 +346,7 @@ fn test_list() {
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	assert list.id == 1
 | 
						assert list.id == 1
 | 
				
			||||||
	assert list.items == ["1", "2"]
 | 
						assert list.items == ['1', '2']
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn test_list_no_id() {
 | 
					fn test_list_no_id() {
 | 
				
			||||||
| 
						 | 
					@ -340,7 +355,7 @@ fn test_list_no_id() {
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	assert list.id == 0
 | 
						assert list.id == 0
 | 
				
			||||||
	assert list.items == ["1", "2"]
 | 
						assert list.items == ['1', '2']
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn test_list_no_items() {
 | 
					fn test_list_no_items() {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,6 +6,7 @@ module big
 | 
				
			||||||
#include "bn.h"
 | 
					#include "bn.h"
 | 
				
			||||||
[typedef]
 | 
					[typedef]
 | 
				
			||||||
struct C.bn {
 | 
					struct C.bn {
 | 
				
			||||||
 | 
					mut:
 | 
				
			||||||
	array [32]u32
 | 
						array [32]u32
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -105,6 +106,18 @@ pub fn from_string(input string) Number {
 | 
				
			||||||
	return n
 | 
						return n
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn from_string2(input string) Number {
 | 
				
			||||||
 | 
						mut n := Number{}
 | 
				
			||||||
 | 
						C.bignum_init(&n)
 | 
				
			||||||
 | 
						if input.len == 0 {
 | 
				
			||||||
 | 
							return from_int(0)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for i, c in input {
 | 
				
			||||||
 | 
							n.array[i] = u32(c - `0`)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return n
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn (n Number) int() int {
 | 
					pub fn (n Number) int() int {
 | 
				
			||||||
	r := C.bignum_to_int(&n)
 | 
						r := C.bignum_to_int(&n)
 | 
				
			||||||
	return r
 | 
						return r
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -78,6 +78,10 @@ fn test_mod() {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn test_from_str() {
 | 
					fn test_from_str() {
 | 
				
			||||||
 | 
						x := big.from_string2('23')
 | 
				
			||||||
 | 
						println('kek')
 | 
				
			||||||
 | 
						println(x.str())
 | 
				
			||||||
 | 
						exit(0)
 | 
				
			||||||
	assert big.from_string('').hexstr() == '0'
 | 
						assert big.from_string('').hexstr() == '0'
 | 
				
			||||||
	assert big.from_string('1').hexstr() == '1'
 | 
						assert big.from_string('1').hexstr() == '1'
 | 
				
			||||||
	assert big.from_string('0').hexstr() == '0'
 | 
						assert big.from_string('0').hexstr() == '0'
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -126,6 +126,7 @@ fn (mut g Gen) gen_struct_enc_dec(type_info table.TypeInfo, styp string, mut enc
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		field_type := g.typ(field.typ)
 | 
							field_type := g.typ(field.typ)
 | 
				
			||||||
		field_sym := g.table.get_type_symbol(field.typ)
 | 
							field_sym := g.table.get_type_symbol(field.typ)
 | 
				
			||||||
 | 
							// First generate decoding
 | 
				
			||||||
		if field.attrs.contains('raw') {
 | 
							if field.attrs.contains('raw') {
 | 
				
			||||||
			dec.writeln('\tres.${c_name(field.name)} = tos4(cJSON_PrintUnformatted(' + 'js_get(root, "$name")));')
 | 
								dec.writeln('\tres.${c_name(field.name)} = tos4(cJSON_PrintUnformatted(' + 'js_get(root, "$name")));')
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
| 
						 | 
					@ -137,6 +138,10 @@ fn (mut g Gen) gen_struct_enc_dec(type_info table.TypeInfo, styp string, mut enc
 | 
				
			||||||
				dec.writeln('\tres.${c_name(field.name)} = $dec_name (js_get(root, "$name"));')
 | 
									dec.writeln('\tres.${c_name(field.name)} = $dec_name (js_get(root, "$name"));')
 | 
				
			||||||
			} else if field_sym.kind == .enum_ {
 | 
								} else if field_sym.kind == .enum_ {
 | 
				
			||||||
				dec.writeln('\tres.${c_name(field.name)} = json__decode_u64(js_get(root, "$name"));')
 | 
									dec.writeln('\tres.${c_name(field.name)} = json__decode_u64(js_get(root, "$name"));')
 | 
				
			||||||
 | 
								} else if field_sym.name == 'time.Time' {
 | 
				
			||||||
 | 
									// time struct requires special treatment
 | 
				
			||||||
 | 
									// it has to be decoded from a unix timestamp number
 | 
				
			||||||
 | 
									dec.writeln('\tres.${c_name(field.name)} = time__unix(json__decode_u64(js_get(root, "$name")));')
 | 
				
			||||||
			} else if field_sym.kind == .alias {
 | 
								} else if field_sym.kind == .alias {
 | 
				
			||||||
				alias := field_sym.info as table.Alias
 | 
									alias := field_sym.info as table.Alias
 | 
				
			||||||
				parent_type := g.typ(alias.parent_type)
 | 
									parent_type := g.typ(alias.parent_type)
 | 
				
			||||||
| 
						 | 
					@ -162,6 +167,7 @@ fn (mut g Gen) gen_struct_enc_dec(type_info table.TypeInfo, styp string, mut enc
 | 
				
			||||||
				dec.writeln('\tres.${c_name(field.name)} = *($field_type*) ${tmp}.data;')
 | 
									dec.writeln('\tres.${c_name(field.name)} = *($field_type*) ${tmp}.data;')
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							// Encoding
 | 
				
			||||||
		mut enc_name := js_enc_name(field_type)
 | 
							mut enc_name := js_enc_name(field_type)
 | 
				
			||||||
		if !is_js_prim(field_type) {
 | 
							if !is_js_prim(field_type) {
 | 
				
			||||||
			if field_sym.kind == .alias {
 | 
								if field_sym.kind == .alias {
 | 
				
			||||||
| 
						 | 
					@ -171,11 +177,17 @@ fn (mut g Gen) gen_struct_enc_dec(type_info table.TypeInfo, styp string, mut enc
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if field_sym.kind == .enum_ {
 | 
							if field_sym.kind == .enum_ {
 | 
				
			||||||
			enc.writeln('\tcJSON_AddItemToObject(o, "$name", json__encode_u64(val.${c_name(field.name)}));')
 | 
								enc.writeln('\tcJSON_AddItemToObject(o, "$name", json__encode_u64(val.${c_name(field.name)}));')
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								if field_sym.name == 'time.Time' {
 | 
				
			||||||
 | 
									// time struct requires special treatment
 | 
				
			||||||
 | 
									// it has to be encoded as a unix timestamp number
 | 
				
			||||||
 | 
									enc.writeln('\tcJSON_AddItemToObject(o, "$name", json__encode_u64(val.${c_name(field.name)}.v_unix));')
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				enc.writeln('\tcJSON_AddItemToObject(o, "$name", ${enc_name}(val.${c_name(field.name)}));')
 | 
									enc.writeln('\tcJSON_AddItemToObject(o, "$name", ${enc_name}(val.${c_name(field.name)}));')
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn js_enc_name(typ string) string {
 | 
					fn js_enc_name(typ string) string {
 | 
				
			||||||
	suffix := if typ.ends_with('*') { typ.replace('*', '') } else { typ }
 | 
						suffix := if typ.ends_with('*') { typ.replace('*', '') } else { typ }
 | 
				
			||||||
| 
						 | 
					@ -189,9 +201,8 @@ fn js_dec_name(typ string) string {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn is_js_prim(typ string) bool {
 | 
					fn is_js_prim(typ string) bool {
 | 
				
			||||||
	return typ == 'int' || typ == 'string' || typ == 'bool' || typ == 'f32' || typ == 'f64' ||
 | 
						return typ in
 | 
				
			||||||
		typ == 'i8' || typ == 'i16' || typ == 'i64' || typ == 'u16' || typ == 'u32' || typ == 'u64' ||
 | 
							['int', 'string', 'bool', 'f32', 'f64', 'i8', 'i16', 'i64', 'u16', 'u32', 'u64', 'byte']
 | 
				
			||||||
		typ == 'byte'
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn (mut g Gen) decode_array(value_type table.Type) string {
 | 
					fn (mut g Gen) decode_array(value_type table.Type) string {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue