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

83 lines
1.7 KiB
V
Raw Normal View History

2022-01-04 12:21:08 +03:00
// Copyright (c) 2019-2022 Alexander Medvednikov. All rights reserved.
2019-08-17 15:51:20 +03:00
// Use of this source code is governed by an MIT license
// that can be found in the LICENSE file.
module csv
import strings
struct Writer {
mut:
sb strings.Builder
2019-12-13 20:45:48 +03:00
pub mut:
2021-01-05 21:14:35 +03:00
use_crlf bool
2022-04-15 18:25:45 +03:00
delimiter u8
2019-08-17 15:51:20 +03:00
}
// new_writer returns a reference to a Writer
2019-09-03 14:57:04 +03:00
pub fn new_writer() &Writer {
2019-08-17 15:51:20 +03:00
return &Writer{
2021-01-05 21:14:35 +03:00
delimiter: `,`
2019-08-17 15:51:20 +03:00
sb: strings.new_builder(200)
}
}
// write writes a single record
2020-05-17 14:51:18 +03:00
pub fn (mut w Writer) write(record []string) ?bool {
2019-08-17 15:51:20 +03:00
if !valid_delim(w.delimiter) {
return IError(&InvalidDelimiterError{})
2019-08-17 15:51:20 +03:00
}
le := if w.use_crlf { '\r\n' } else { '\n' }
for n, field_ in record {
mut field := field_
2019-08-17 15:51:20 +03:00
if n > 0 {
w.sb.write_string(w.delimiter.ascii_str())
2019-08-17 15:51:20 +03:00
}
if !w.field_needs_quotes(field) {
w.sb.write_string(field)
2019-08-17 15:51:20 +03:00
continue
}
w.sb.write_string('"')
2019-08-17 15:51:20 +03:00
for field.len > 0 {
mut i := field.index_any('"\r\n')
if i < 0 {
i = field.len
}
w.sb.write_string(field[..i])
field = field[i..]
2019-08-17 15:51:20 +03:00
if field.len > 0 {
z := field[0]
2019-10-27 12:36:38 +03:00
match z {
`"` { w.sb.write_string('""') }
`\r`, `\n` { w.sb.write_string(le) }
else {}
2019-10-27 12:36:38 +03:00
}
field = field[1..]
2019-08-17 15:51:20 +03:00
}
}
w.sb.write_string('"')
2019-08-17 15:51:20 +03:00
}
w.sb.write_string(le)
2019-08-17 15:51:20 +03:00
return true
}
// Once we have multi dimensional array
// pub fn (w &Writer) write_all(records [][]string) {
// for _, record in records {
// w.write(record)
// }
// }
fn (w &Writer) field_needs_quotes(field string) bool {
if field == '' {
return false
}
2021-01-05 21:14:35 +03:00
if field.contains(w.delimiter.ascii_str()) || (field.index_any('"\r\n') != -1) {
2019-08-17 15:51:20 +03:00
return true
}
return false
}
// str returns the writer contents
2020-05-17 14:51:18 +03:00
pub fn (mut w Writer) str() string {
2019-08-17 15:51:20 +03:00
return w.sb.str()
}