1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

all: comptime type lowercase ($int, $enum, $option, etc) (#17732)

This commit is contained in:
Felipe Pena 2023-03-22 20:02:42 -03:00 committed by GitHub
parent 0afb41f7e1
commit 9a9cfe425c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 203 additions and 122 deletions

View File

@ -139,17 +139,17 @@ pub:
pub fn (cty ComptimeType) str() string { pub fn (cty ComptimeType) str() string {
return match cty.kind { return match cty.kind {
.map_ { '\$Map' } .map_ { '\$map' }
.int { '\$Int' } .int { '\$int' }
.float { '\$Float' } .float { '\$float' }
.struct_ { '\$Struct' } .struct_ { '\$struct' }
.iface { '\$Interface' } .iface { '\$interface' }
.array { '\$Array' } .array { '\$array' }
.sum_type { '\$Sumtype' } .sum_type { '\$sumtype' }
.enum_ { '\$Enum' } .enum_ { '\$enum' }
.alias { '\$Alias' } .alias { '\$alias' }
.function { '\$Function' } .function { '\$function' }
.option { '\$Option' } .option { '\$option' }
} }
} }

View File

@ -732,17 +732,17 @@ pub fn (mut f Fmt) expr(node_ ast.Expr) {
} }
ast.ComptimeType { ast.ComptimeType {
match node.kind { match node.kind {
.array { f.write('\$Array') } .array { f.write('\$array') }
.struct_ { f.write('\$Struct') } .struct_ { f.write('\$struct') }
.iface { f.write('\$Interface') } .iface { f.write('\$interface') }
.map_ { f.write('\$Map') } .map_ { f.write('\$map') }
.int { f.write('\$Int') } .int { f.write('\$int') }
.float { f.write('\$Float') } .float { f.write('\$float') }
.sum_type { f.write('\$Sumtype') } .sum_type { f.write('\$sumtype') }
.enum_ { f.write('\$Enum') } .enum_ { f.write('\$enum') }
.alias { f.write('\$Alias') } .alias { f.write('\$alias') }
.function { f.write('\$Function') } .function { f.write('\$function') }
.option { f.write('\$Option') } .option { f.write('\$option') }
} }
} }
} }

View File

@ -651,17 +651,17 @@ pub fn (mut f Gen) expr(node_ ast.Expr) {
} }
ast.ComptimeType { ast.ComptimeType {
match node.kind { match node.kind {
.array { f.write('\$Array') } .array { f.write('\$array') }
.struct_ { f.write('\$Struct') } .struct_ { f.write('\$struct') }
.iface { f.write('\$Interface') } .iface { f.write('\$interface') }
.map_ { f.write('\$Map') } .map_ { f.write('\$map') }
.int { f.write('\$Int') } .int { f.write('\$int') }
.float { f.write('\$Float') } .float { f.write('\$float') }
.sum_type { f.write('\$Sumtype') } .sum_type { f.write('\$sumtype') }
.enum_ { f.write('\$Enum') } .enum_ { f.write('\$enum') }
.alias { f.write('\$Alias') } .alias { f.write('\$alias') }
.function { f.write('\$Function') } .function { f.write('\$function') }
.option { f.write('\$Option') } .option { f.write('\$option') }
} }
} }
} }

View File

@ -11,8 +11,8 @@ import v.token
const ( const (
supported_comptime_calls = ['html', 'tmpl', 'env', 'embed_file', 'pkgconfig', 'compile_error', supported_comptime_calls = ['html', 'tmpl', 'env', 'embed_file', 'pkgconfig', 'compile_error',
'compile_warn'] 'compile_warn']
comptime_types = ['Map', 'Array', 'Int', 'Float', 'Struct', 'Interface', 'Enum', comptime_types = ['map', 'array', 'int', 'float', 'struct', 'interface', 'enum',
'Sumtype', 'Alias', 'Function', 'Option'] 'sumtype', 'alias', 'function', 'option']
) )
pub fn (mut p Parser) parse_comptime_type() ast.ComptimeType { pub fn (mut p Parser) parse_comptime_type() ast.ComptimeType {
@ -25,37 +25,37 @@ pub fn (mut p Parser) parse_comptime_type() ast.ComptimeType {
} }
mut cty := ast.ComptimeTypeKind.map_ mut cty := ast.ComptimeTypeKind.map_
match name { match name {
'Map' { 'map' {
cty = .map_ cty = .map_
} }
'Struct' { 'struct' {
cty = .struct_ cty = .struct_
} }
'Interface' { 'interface' {
cty = .iface cty = .iface
} }
'Int' { 'int' {
cty = .int cty = .int
} }
'Float' { 'float' {
cty = .float cty = .float
} }
'Alias' { 'alias' {
cty = .alias cty = .alias
} }
'Function' { 'function' {
cty = .function cty = .function
} }
'Array' { 'array' {
cty = .array cty = .array
} }
'Enum' { 'enum' {
cty = .enum_ cty = .enum_
} }
'Sumtype' { 'sumtype' {
cty = .sum_type cty = .sum_type
} }
'Option' { 'option' {
cty = .option cty = .option
} }
else {} else {}

View File

@ -79,7 +79,7 @@ pub fn (mut p Parser) check_expr(precedence int) !ast.Expr {
} }
.dollar { .dollar {
match p.peek_tok.kind { match p.peek_tok.kind {
.name { .name, .key_struct, .key_enum, .key_interface {
if p.peek_tok.lit in comptime_types { if p.peek_tok.lit in comptime_types {
node = p.parse_comptime_type() node = p.parse_comptime_type()
} else { } else {

View File

@ -674,7 +674,12 @@ fn (mut p Parser) check_name() string {
if p.peek_tok.kind == .dot && name in p.imports { if p.peek_tok.kind == .dot && name in p.imports {
p.register_used_import(name) p.register_used_import(name)
} }
p.check(.name) match p.tok.kind {
.key_struct { p.check(.key_struct) }
.key_enum { p.check(.key_enum) }
.key_interface { p.check(.key_interface) }
else { p.check(.name) }
}
return name return name
} }

View File

@ -7,7 +7,7 @@ fn main() {
} }
fn func[T](mut t T) { fn func[T](mut t T) {
$if T is $Array { $if T is $array {
for i in 0 .. t.len { for i in 0 .. t.len {
println(t[i]) println(t[i])
} }

View File

@ -10,15 +10,15 @@ pub fn func1[T](t &T) {
[inline] [inline]
pub fn func2[T](t &T) { pub fn func2[T](t &T) {
$if T is $Array { $if T is $array {
unsafe { unsafe {
for i in 0 .. t.len { for i in 0 .. t.len {
func2(&t[i]) func2(&t[i])
} }
} }
} $else $if T is $Map { } $else $if T is $map {
// fake_map(t, df) // fake_map(t, df)
} $else $if T is $Struct { } $else $if T is $struct {
$for f in T.fields { $for f in T.fields {
$if f.typ is string { $if f.typ is string {
} }

View File

@ -11,19 +11,19 @@ struct Test {
} }
fn check[T](val T) string { fn check[T](val T) string {
$if T in [$Array, $Struct] { $if T in [$array, $struct] {
return 'array or struct' return 'array or struct'
} $else $if T in [u8, u16, u32] { } $else $if T in [u8, u16, u32] {
return 'unsigned int' return 'unsigned int'
} $else $if T in [int, $Int] { } $else $if T in [int, $int] {
return 'int' return 'int'
} $else $if T in [$Float, f64, f32] { } $else $if T in [$float, f64, f32] {
return 'f64' return 'f64'
} $else $if T in [$Map, map] { } $else $if T in [$map, map] {
return 'map' return 'map'
} $else $if T in [Abc, Abc] { } $else $if T in [Abc, Abc] {
return 'Abc' return 'Abc'
} $else $if T in [$Sumtype, Abc] { } $else $if T in [$sumtype, Abc] {
return 'sumtype' return 'sumtype'
} }
@ -32,22 +32,22 @@ fn check[T](val T) string {
fn check_not[T](val T) string { fn check_not[T](val T) string {
mut str := string{} mut str := string{}
$if T !in [$Array, $Array] { $if T !in [$array, $array] {
str += '1' str += '1'
} }
$if T !in [u8, u16, u32] { $if T !in [u8, u16, u32] {
str += '2' str += '2'
} }
$if T !in [int, $Int] { $if T !in [int, $int] {
str += '3' str += '3'
} }
$if T !in [$Float, f64, f32] { $if T !in [$float, f64, f32] {
str += '4' str += '4'
} $else $if T !in [$Map, map] { } $else $if T !in [$map, map] {
str += '5' str += '5'
} $else $if T !in [Abc, Abc] { } $else $if T !in [Abc, Abc] {
str += '6' str += '6'
} $else $if T !in [$Sumtype, Abc] { } $else $if T !in [$sumtype, Abc] {
str += '7' str += '7'
} }

View File

@ -1,5 +1,5 @@
fn assert_map[T]() { fn assert_map[T]() {
$if T is $Map { $if T is $map {
assert true assert true
} $else { } $else {
assert false assert false
@ -7,7 +7,7 @@ fn assert_map[T]() {
} }
fn assert_array[T]() { fn assert_array[T]() {
$if T is $Array { $if T is $array {
assert true assert true
} $else { } $else {
assert false assert false
@ -15,7 +15,7 @@ fn assert_array[T]() {
} }
fn assert_struct[T]() { fn assert_struct[T]() {
$if T is $Struct { $if T is $struct {
assert true assert true
} $else { } $else {
assert false assert false
@ -23,7 +23,7 @@ fn assert_struct[T]() {
} }
fn assert_not_struct[T]() { fn assert_not_struct[T]() {
$if T is $Struct { $if T is $struct {
assert false assert false
} $else { } $else {
assert true assert true
@ -31,7 +31,7 @@ fn assert_not_struct[T]() {
} }
fn assert_not_map[T]() { fn assert_not_map[T]() {
$if T is $Map { $if T is $map {
assert false assert false
} $else { } $else {
assert true assert true
@ -39,7 +39,7 @@ fn assert_not_map[T]() {
} }
fn assert_not_array[T]() { fn assert_not_array[T]() {
$if T is $Array { $if T is $array {
assert false assert false
} $else { } $else {
assert true assert true
@ -90,7 +90,7 @@ type AliasOfint = int
type AliasOfstring = string type AliasOfstring = string
fn assert_alias[T]() { fn assert_alias[T]() {
$if T is $Alias { $if T is $alias {
assert true assert true
} $else { } $else {
assert false assert false
@ -98,7 +98,7 @@ fn assert_alias[T]() {
} }
fn assert_not_alias[T]() { fn assert_not_alias[T]() {
$if T is $Alias { $if T is $alias {
assert false assert false
} $else { } $else {
assert true assert true
@ -119,7 +119,7 @@ fn test_kind_alias() {
// //
fn assert_function[T](f T) { fn assert_function[T](f T) {
$if T is $Function { $if T is $function {
assert true assert true
} $else { } $else {
assert false assert false
@ -127,7 +127,7 @@ fn assert_function[T](f T) {
} }
fn assert_not_function[T](f T) { fn assert_not_function[T](f T) {
$if T is $Function { $if T is $function {
assert false assert false
} $else { } $else {
assert true assert true

View File

@ -27,7 +27,7 @@ fn test_comptimeselector_map_different_types() {
mut vals := []string{} mut vals := []string{}
$for field in Data.fields { $for field in Data.fields {
$if field.typ is $Map { $if field.typ is $map {
for k, v in data.$(field.name) { for k, v in data.$(field.name) {
keys << k.str() keys << k.str()
vals << v.str() vals << v.str()
@ -57,7 +57,7 @@ fn test_comptime_var_map_different_types() {
mut vals := []string{} mut vals := []string{}
$for field in Data.fields { $for field in Data.fields {
$if field.typ is $Map { $if field.typ is $map {
gg := data.$(field.name) gg := data.$(field.name)
for k, v in gg { for k, v in gg {
keys << k.str() keys << k.str()
@ -85,7 +85,7 @@ fn test_comptime_with_dump() {
} }
$for field in Data.fields { $for field in Data.fields {
$if field.typ is $Map { $if field.typ is $map {
for k, v in data.$(field.name) { for k, v in data.$(field.name) {
dump(k) dump(k)
dump(v) dump(v)
@ -111,7 +111,7 @@ fn test_comptime_dump_for_key_and_value() {
mut val_types := []string{} mut val_types := []string{}
$for field in Data.fields { $for field in Data.fields {
$if field.typ is $Map { $if field.typ is $map {
for k, v in data.$(field.name) { for k, v in data.$(field.name) {
key_types << typeof(k).name key_types << typeof(k).name
val_types << typeof(v).name val_types << typeof(v).name
@ -141,7 +141,7 @@ fn test_comptime_key_value_var() {
mut vals := []string{} mut vals := []string{}
$for field in Data.fields { $for field in Data.fields {
$if field.typ is $Map { $if field.typ is $map {
for k, v in data.$(field.name) { for k, v in data.$(field.name) {
if k == 'a' { if k == 'a' {
keys << dump(k) keys << dump(k)
@ -176,7 +176,7 @@ fn test_comptime_generic_argument() {
} }
$for field in Data.fields { $for field in Data.fields {
$if field.typ is $Map { $if field.typ is $map {
for k, v in data.$(field.name) { for k, v in data.$(field.name) {
process_value_from_map(v) process_value_from_map(v)
assert k in ['a', 'b'] assert k in ['a', 'b']
@ -186,12 +186,12 @@ fn test_comptime_generic_argument() {
} }
fn process_value_from_map[T](v T) { fn process_value_from_map[T](v T) {
$if T is $Map { $if T is $map {
assert typeof(v).name == 'map[string]int' assert typeof(v).name == 'map[string]int'
assert v.str() == "{'c': 10}" assert v.str() == "{'c': 10}"
assert true assert true
return return
} $else $if T is $Struct { } $else $if T is $struct {
assert typeof(v).name == 'StructType' assert typeof(v).name == 'StructType'
assert v.str() == "StructType{ assert v.str() == "StructType{
val: 'string from StructType' val: 'string from StructType'

View File

@ -10,7 +10,7 @@ struct Test {
fn test_option_comptime() { fn test_option_comptime() {
mut opts := []string{} mut opts := []string{}
$for f in Test.fields { $for f in Test.fields {
$if f.typ is $Option { $if f.typ is $option {
opts << f.name opts << f.name
} }
} }

View File

@ -10,7 +10,7 @@ fn test_main() {
} }
fn map_from[T](t T) { fn map_from[T](t T) {
$if T is $Struct { $if T is $struct {
$for field in T.fields { $for field in T.fields {
assert Any('string').str() == "Any('string')" assert Any('string').str() == "Any('string')"
assert t.$(field.name).str() == 'true' assert t.$(field.name).str() == 'true'

View File

@ -0,0 +1,76 @@
interface Abc {}
enum EnumTest {
a
b
}
type Alias = Abc
type Sumtype = int | string
struct Foo {}
struct Test {
a Abc
b map[string]string
c []int
d EnumTest
e int
f f64
g Alias
h Foo
i fn ()
j Sumtype
k ?int
}
fn test_comptime_types() {
mut i := 0
mut a := 0
mut m := 0
mut e := 0
mut c_int := 0
mut c_float := 0
mut c_alias := 0
mut c_struct := 0
mut c_fn := 0
mut c_sum := 0
mut c_option := 0
$for f in Test.fields {
$if f.typ is $alias {
c_alias++
} $else $if f.typ is $interface {
i++
} $else $if f.typ is $array {
a++
} $else $if f.typ is $map {
m++
} $else $if f.typ is $enum {
e++
} $else $if f.typ is $int {
c_int++
} $else $if f.typ is $float {
c_float++
} $else $if f.typ is $struct {
c_struct++
} $else $if f.typ is $function {
c_fn++
} $else $if f.typ is $sumtype {
c_sum++
} $else $if f.typ is $option {
c_option++
}
}
assert i == 1
assert a == 1
assert m == 1
assert e == 1
assert c_int == 1
assert c_float == 1
assert c_alias == 1
assert c_struct == 1
assert c_fn == 1
assert c_sum == 1
assert c_option == 1
}

View File

@ -6,7 +6,7 @@ fn encode_array[U](val []U) []string {
mut out := []string{} mut out := []string{}
$if U is int { $if U is int {
out << 'is int' out << 'is int'
} $else $if U is $Struct { } $else $if U is $struct {
out << 'is struct' out << 'is struct'
} }
return out return out

View File

@ -6,7 +6,7 @@ fn fn_a[T](data T, depth int, nl bool) {
print('int: ${data}') print('int: ${data}')
} $else $if T.typ is string { } $else $if T.typ is string {
print('string: ${data}') print('string: ${data}')
} $else $if T is $Array { } $else $if T is $array {
println('array: [') println('array: [')
for i, elem in data { for i, elem in data {
fn_a(elem, depth + 1, false) fn_a(elem, depth + 1, false)
@ -16,7 +16,7 @@ fn fn_a[T](data T, depth int, nl bool) {
println('') println('')
} }
print(']') print(']')
} $else $if T is $Map { } $else $if T is $map {
println('map: {') println('map: {')
for key, value in data { for key, value in data {
print('\t(key) ') print('\t(key) ')
@ -25,7 +25,7 @@ fn fn_a[T](data T, depth int, nl bool) {
fn_a(value, depth, true) fn_a(value, depth, true)
} }
print('}') print('}')
} $else $if T is $Struct { } $else $if T is $struct {
println('struct ${T.name}: {') println('struct ${T.name}: {')
$for field in T.fields { $for field in T.fields {
print('\t(${field.name}) ') print('\t(${field.name}) ')

View File

@ -4,7 +4,7 @@ fn (t Test) test[T](val T) {
$for f in T.fields { $for f in T.fields {
value := val.$(f.name) value := val.$(f.name)
$if f.is_option { $if f.is_option {
$if f.typ is $Struct { $if f.typ is $struct {
_ := 1 _ := 1
t.test(value) t.test(value)
} $else $if f.typ is string { } $else $if f.typ is string {
@ -15,7 +15,7 @@ fn (t Test) test[T](val T) {
_ := 4 _ := 4
} }
} $else { } $else {
$if f.typ is $Struct { $if f.typ is $struct {
t.test(value) t.test(value)
} $else $if f.typ is string { } $else $if f.typ is string {
_ := 5 _ := 5

View File

@ -13,7 +13,7 @@ fn (e &Encoder) encode_array[T](val []T) []T {
fn encode_struct[T](val T) []string { fn encode_struct[T](val T) []string {
e := Encoder{} e := Encoder{}
mut out := []string{} mut out := []string{}
$if T is $Struct { $if T is $struct {
$for field in T.fields { $for field in T.fields {
out << field.name out << field.name
out << field.is_array.str() out << field.is_array.str()

View File

@ -23,7 +23,7 @@ fn (wr &Writer) write2[T](val T) {
fn encode_struct[T](val T) map[string][]string { fn encode_struct[T](val T) map[string][]string {
wr := Writer{} wr := Writer{}
mut out := map[string][]string{} mut out := map[string][]string{}
$if T is $Struct { $if T is $struct {
$for field in T.fields { $for field in T.fields {
value := val.$(field.name) value := val.$(field.name)
$if field.typ is ?int { $if field.typ is ?int {

View File

@ -14,7 +14,7 @@ fn new_static_router2(route_not_found_handler ?HandlerFn) fn () {
fn test_option_fn_alias_decl_with_none() { fn test_option_fn_alias_decl_with_none() {
b := new_static_router2(none) b := new_static_router2(none)
$if b is $Function { $if b is $function {
assert true assert true
} $else { } $else {
assert false assert false
@ -23,7 +23,7 @@ fn test_option_fn_alias_decl_with_none() {
fn test_option_fn_decl_with_none() { fn test_option_fn_decl_with_none() {
a := new_static_router(none) a := new_static_router(none)
$if a is $Function { $if a is $function {
assert true assert true
} $else { } $else {
assert false assert false

View File

@ -16,16 +16,16 @@ fn test_main() {
mut out := map[string][]string{} mut out := map[string][]string{}
$for field in Foo.fields { $for field in Foo.fields {
print('${field.name} is ') print('${field.name} is ')
$if field.unaliased_typ is $Int { $if field.unaliased_typ is $int {
println('numeric') println('numeric')
out[field.name] << 'numeric' out[field.name] << 'numeric'
} $else $if field.unaliased_typ is $Array { } $else $if field.unaliased_typ is $array {
println('array') println('array')
out[field.name] << 'array' out[field.name] << 'array'
} $else $if field.unaliased_typ is $Float { } $else $if field.unaliased_typ is $float {
println('float') println('float')
out[field.name] << 'float' out[field.name] << 'float'
} $else $if field.unaliased_typ is $Map { } $else $if field.unaliased_typ is $map {
println('map') println('map')
out[field.name] << 'map' out[field.name] << 'map'
} $else $if field.unaliased_typ is string || field.unaliased_typ is ?string { } $else $if field.unaliased_typ is string || field.unaliased_typ is ?string {

View File

@ -5,18 +5,18 @@ struct Test {
fn test_main() { fn test_main() {
hh := 1 // i64(4) hh := 1 // i64(4)
$if hh is $Int { $if hh is $int {
println('int') println('int')
assert true assert true
} $else $if hh !is $Int { } $else $if hh !is $int {
println('string') println('string')
assert false assert false
} }
b := 1.2 b := 1.2
$if b is $Int { $if b is $int {
assert false assert false
} $else $if b is $Float { } $else $if b is $float {
println('float') println('float')
assert true assert true
} }

View File

@ -132,11 +132,11 @@ fn (e &Encoder) encode_value_with_level[T](val T, level int, mut wr io.Writer) !
e.encode_any(val, level, mut wr)! e.encode_any(val, level, mut wr)!
} $else $if T is Encodable { } $else $if T is Encodable {
wr.write(val.json_str().bytes())! wr.write(val.json_str().bytes())!
} $else $if T is $Struct { } $else $if T is $struct {
e.encode_struct(val, level, mut wr)! e.encode_struct(val, level, mut wr)!
} $else $if T is $Enum { } $else $if T is $enum {
e.encode_any(Any(int(val)), level, mut wr)! e.encode_any(Any(int(val)), level, mut wr)!
} $else $if T in [Null, bool, $Float, $Int] { } $else $if T in [Null, bool, $float, $int] {
e.encode_any(val, level, mut wr)! e.encode_any(val, level, mut wr)!
} $else { } $else {
// dump(val.str()) // dump(val.str())
@ -245,21 +245,21 @@ fn (e &Encoder) encode_struct[U](val U, level int, mut wr io.Writer) ! {
wr.write(json2.quote_bytes)! wr.write(json2.quote_bytes)!
wr.write(val.$(field.name).format_rfc3339().bytes())! wr.write(val.$(field.name).format_rfc3339().bytes())!
wr.write(json2.quote_bytes)! wr.write(json2.quote_bytes)!
} $else $if field.typ in [bool, $Float, $Int] { } $else $if field.typ in [bool, $float, $int] {
wr.write(val.$(field.name).str().bytes())! wr.write(val.$(field.name).str().bytes())!
} $else $if field.is_array { } $else $if field.is_array {
// TODO - replace for `field.typ is $Array` // TODO - replace for `field.typ is $array`
e.encode_array(value, level + 1, mut wr)! e.encode_array(value, level + 1, mut wr)!
} $else $if field.typ is $Array { } $else $if field.typ is $array {
// e.encode_array(value, level + 1, mut wr)! // FIXME - error: could not infer generic type `U` in call to `encode_array` // e.encode_array(value, level + 1, mut wr)! // FIXME - error: could not infer generic type `U` in call to `encode_array`
} $else $if field.typ is $Struct { } $else $if field.typ is $struct {
e.encode_struct(value, level + 1, mut wr)! e.encode_struct(value, level + 1, mut wr)!
} $else $if field.is_enum { } $else $if field.is_enum {
// TODO - replace for `field.typ is $Enum` // TODO - replace for `field.typ is $enum`
wr.write(int(val.$(field.name)).str().bytes())! wr.write(int(val.$(field.name)).str().bytes())!
} $else $if field.typ is $Enum { } $else $if field.typ is $enum {
// wr.write(int(val.$(field.name)).str().bytes())! // FIXME - error: cannot cast string to `int`, use `val.$field.name.int()` instead. // wr.write(int(val.$(field.name)).str().bytes())! // FIXME - error: cannot cast string to `int`, use `val.$field.name.int()` instead.
} $else $if field.typ is $Sumtype { } $else $if field.typ is $sumtype {
// dump(val.$(field.name).str()) // dump(val.$(field.name).str())
// dump(is_none) // dump(is_none)
sum_type_value := value.str()#[typeof(val.$(field.name)).name.len + 1..-1] sum_type_value := value.str()#[typeof(val.$(field.name)).name.len + 1..-1]
@ -319,27 +319,27 @@ fn (e &Encoder) encode_struct[U](val U, level int, mut wr io.Writer) ! {
if is_string { if is_string {
e.encode_string(sum_type_value#[1..-1], mut wr)! e.encode_string(sum_type_value#[1..-1], mut wr)!
} }
} $else $if field.typ is $Alias { } $else $if field.typ is $alias {
$if field.unaliased_typ is string { $if field.unaliased_typ is string {
e.encode_string(val.$(field.name).str(), mut wr)! e.encode_string(val.$(field.name).str(), mut wr)!
} $else $if field.unaliased_typ is time.Time { } $else $if field.unaliased_typ is time.Time {
parsed_time := time.parse(val.$(field.name).str()) or { time.Time{} } parsed_time := time.parse(val.$(field.name).str()) or { time.Time{} }
e.encode_string(parsed_time.format_rfc3339(), mut wr)! e.encode_string(parsed_time.format_rfc3339(), mut wr)!
} $else $if field.unaliased_typ in [bool, $Float, $Int] { } $else $if field.unaliased_typ in [bool, $float, $int] {
wr.write(val.$(field.name).str().bytes())! wr.write(val.$(field.name).str().bytes())!
} $else $if field.unaliased_typ is $Array { } $else $if field.unaliased_typ is $array {
// e.encode_array(val.$(field.name), level + 1, mut wr)! // FIXME - error: could not infer generic type `U` in call to `encode_array` // e.encode_array(val.$(field.name), level + 1, mut wr)! // FIXME - error: could not infer generic type `U` in call to `encode_array`
} $else $if field.unaliased_typ is $Struct { } $else $if field.unaliased_typ is $struct {
// e.encode_struct(val.$(field.name), level + 1, mut wr)! // FIXME - error: cannot use `BoolAlias` as `StringAlias` in argument 1 to `x.json2.Encoder.encode_struct` // e.encode_struct(val.$(field.name), level + 1, mut wr)! // FIXME - error: cannot use `BoolAlias` as `StringAlias` in argument 1 to `x.json2.Encoder.encode_struct`
e.encode_struct(value, level + 1, mut wr)! e.encode_struct(value, level + 1, mut wr)!
} $else $if field.unaliased_typ is $Enum { } $else $if field.unaliased_typ is $enum {
// enum_value := val.$(field.name) // enum_value := val.$(field.name)
// dump(int(val.$(field.name))) // FIXME // dump(int(val.$(field.name))) // FIXME
// dump(val.$(field.name).int()) // FIXME - error: unknown method or field: `BoolAlias.int` // dump(val.$(field.name).int()) // FIXME - error: unknown method or field: `BoolAlias.int`
// dump(val.$(field.name).int()) // FIXME - error: cannot convert 'enum <anonymous>' to 'struct string' // dump(val.$(field.name).int()) // FIXME - error: cannot convert 'enum <anonymous>' to 'struct string'
// wr.write(val.$(field.name).int().str().bytes())! // FIXME - error: unknown method or field: `BoolAlias.int` // wr.write(val.$(field.name).int().str().bytes())! // FIXME - error: unknown method or field: `BoolAlias.int`
} $else $if field.unaliased_typ is $Sumtype { } $else $if field.unaliased_typ is $sumtype {
} $else { } $else {
return error('the alias ${typeof(val).name} cannot be encoded') return error('the alias ${typeof(val).name} cannot be encoded')
} }
@ -390,18 +390,18 @@ fn (e &Encoder) encode_array[U](val []U, level int, mut wr io.Writer) ! {
e.encode_any(u32(val[i]), level + 1, mut wr)! e.encode_any(u32(val[i]), level + 1, mut wr)!
} $else $if U is u64 { } $else $if U is u64 {
e.encode_any(u64(val[i]), level + 1, mut wr)! e.encode_any(u64(val[i]), level + 1, mut wr)!
} $else $if U is $Array { } $else $if U is $array {
// FIXME - error: could not infer generic type `U` in call to `encode_array` // FIXME - error: could not infer generic type `U` in call to `encode_array`
// e.encode_array(val[i], level + 1, mut wr)! // e.encode_array(val[i], level + 1, mut wr)!
} $else $if U is $Struct { } $else $if U is $struct {
e.encode_struct(val[i], level + 1, mut wr)! e.encode_struct(val[i], level + 1, mut wr)!
} $else $if U is $Sumtype { } $else $if U is $sumtype {
$if U is Any { $if U is Any {
e.encode_any(val[i], level + 1, mut wr)! e.encode_any(val[i], level + 1, mut wr)!
} $else { } $else {
// TODO // TODO
} }
} $else $if U is $Enum { } $else $if U is $enum {
e.encode_any(i64(val[i]), level + 1, mut wr)! e.encode_any(i64(val[i]), level + 1, mut wr)!
} $else { } $else {
return error('type ${typeof(val).name} cannot be array encoded') return error('type ${typeof(val).name} cannot be array encoded')

View File

@ -135,7 +135,7 @@ pub fn decode[T](src string) !T {
// encode is a generic function that encodes a type into a JSON string. // encode is a generic function that encodes a type into a JSON string.
pub fn encode[T](val T) string { pub fn encode[T](val T) string {
$if T is $Array { $if T is $array {
$compile_error('Cannot use `json.encode` to encode array. Try `json.encode_array` instead') $compile_error('Cannot use `json.encode` to encode array. Try `json.encode_array` instead')
} }
mut sb := strings.new_builder(64) mut sb := strings.new_builder(64)
@ -406,7 +406,7 @@ pub fn (f Any) to_time() !time.Time {
fn map_from[T](t T) map[string]Any { fn map_from[T](t T) map[string]Any {
mut m := map[string]Any{} mut m := map[string]Any{}
$if T is $Struct { $if T is $struct {
$for field in T.fields { $for field in T.fields {
value := t.$(field.name) value := t.$(field.name)