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

encoding.csv: generic serialization (#15097)

This commit is contained in:
boris-741 2022-07-16 22:21:05 +03:00 committed by GitHub
parent 8d24522d02
commit b4dedcae43
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 94 additions and 0 deletions

View File

@ -279,3 +279,30 @@ fn test_field_double_quotes() {
}
assert row_count == 3
}
struct Test {
id int
bonus string
amount int
}
fn test_decode_to_struct() {
text := 'id,bonus,amount\r\n1,bomb,1\r\n2,rocket,1\r\n3,lightning,2\r\n'
arr := csv.decode<Test>(text)
for i, val in arr {
if i == 0 {
assert val.id == 1
assert val.bonus == 'bomb'
assert val.amount == 1
} else if i == 1 {
assert val.id == 2
assert val.bonus == 'rocket'
assert val.amount == 1
} else if i == 2 {
assert val.id == 3
assert val.bonus == 'lightning'
assert val.amount == 2
}
}
assert arr.len == 3
}

View File

@ -0,0 +1,67 @@
module csv
import strconv
// decode csv to struct
pub fn decode<T>(data string) []T {
mut result := []T{}
if data == '' {
return result
}
mut parser := new_reader(data)
mut columns_names := []string{}
mut i := 0
for {
items := parser.read() or { break }
if i == 0 {
for val in items {
columns_names << val
}
} else {
mut t_val := T{}
$for field in T.fields {
col := get_column(field.name, columns_names)
if col > -1 && col < items.len {
$if field.typ is string {
t_val.$(field.name) = items[col]
} $else $if field.typ is int {
t_val.$(field.name) = items[col].int()
} $else $if field.typ is f32 {
t_val.$(field.name) = f32(strconv.atof64(items[col]) or { f32(0.0) })
} $else $if field.typ is f64 {
t_val.$(field.name) = strconv.atof64(items[col]) or { f64(0.0) }
} $else $if field.typ is bool {
t_val.$(field.name) = string_to_bool(items[col])
}
}
}
result << t_val
}
i++
}
return result
}
fn string_to_bool(val string) bool {
l_val := val.to_lower().trim_space()
i_val := val.int()
if l_val == 'true' {
return true
}
if i_val == 1 {
return true
}
return false
}
fn get_column(name string, columns []string) int {
for i, val in columns {
if val == name {
return i
}
}
return -1
}