50 lines
1.0 KiB
V
50 lines
1.0 KiB
V
|
// An example deserializer implementation
|
||
|
|
||
|
struct User {
|
||
|
name string
|
||
|
age int
|
||
|
}
|
||
|
|
||
|
fn main() {
|
||
|
data := 'name=Alice\nage=18'
|
||
|
user := decode<User>(data)
|
||
|
println(user)
|
||
|
}
|
||
|
|
||
|
fn decode<T>(data string) T {
|
||
|
mut result := T{}
|
||
|
// compile-time `for` loop
|
||
|
// T.fields gives an array of a field metadata type
|
||
|
$for field in T.fields {
|
||
|
$if field.typ is string {
|
||
|
// $(string_expr) produces an identifier
|
||
|
result.$(field.name) = get_string(data, field.name)
|
||
|
} $else $if field.typ is int {
|
||
|
result.$(field.name) = get_int(data, field.name)
|
||
|
}
|
||
|
}
|
||
|
return result
|
||
|
}
|
||
|
|
||
|
fn get_string(data string, field_name string) string {
|
||
|
for line in data.split_into_lines() {
|
||
|
key_val := line.split('=')
|
||
|
if key_val[0] == field_name {
|
||
|
return key_val[1]
|
||
|
}
|
||
|
}
|
||
|
return ''
|
||
|
}
|
||
|
|
||
|
fn get_int(data string, field string) int {
|
||
|
return get_string(data, field).int()
|
||
|
}
|
||
|
|
||
|
// `decode<User>` generates:
|
||
|
// fn decode_User(data string) User {
|
||
|
// mut result := User{}
|
||
|
// result.name = get_string(data, 'name')
|
||
|
// result.age = get_int(data, 'age')
|
||
|
// return result
|
||
|
// }
|