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 {
|
2020-06-01 18:24:38 +03:00
|
|
|
mut:
|
2021-03-30 15:27:26 +03:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2022-04-30 12:31:23 +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) {
|
2022-02-12 12:54:10 +03:00
|
|
|
return IError(&InvalidDelimiterError{})
|
2019-08-17 15:51:20 +03:00
|
|
|
}
|
|
|
|
le := if w.use_crlf { '\r\n' } else { '\n' }
|
2020-07-05 16:27:37 +03:00
|
|
|
for n, field_ in record {
|
|
|
|
mut field := field_
|
2019-08-17 15:51:20 +03:00
|
|
|
if n > 0 {
|
2021-02-23 10:42:48 +03:00
|
|
|
w.sb.write_string(w.delimiter.ascii_str())
|
2019-08-17 15:51:20 +03:00
|
|
|
}
|
|
|
|
if !w.field_needs_quotes(field) {
|
2021-02-23 10:42:48 +03:00
|
|
|
w.sb.write_string(field)
|
2019-08-17 15:51:20 +03:00
|
|
|
continue
|
|
|
|
}
|
2021-02-23 10:42:48 +03:00
|
|
|
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
|
|
|
|
}
|
2021-02-23 10:42:48 +03:00
|
|
|
w.sb.write_string(field[..i])
|
2019-10-27 10:03:15 +03:00
|
|
|
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 {
|
2021-02-23 10:42:48 +03:00
|
|
|
`"` { w.sb.write_string('""') }
|
|
|
|
`\r`, `\n` { w.sb.write_string(le) }
|
2019-12-07 17:13:25 +03:00
|
|
|
else {}
|
2019-10-27 12:36:38 +03:00
|
|
|
}
|
2019-10-27 10:03:15 +03:00
|
|
|
field = field[1..]
|
2019-08-17 15:51:20 +03:00
|
|
|
}
|
|
|
|
}
|
2021-02-23 10:42:48 +03:00
|
|
|
w.sb.write_string('"')
|
2019-08-17 15:51:20 +03:00
|
|
|
}
|
2021-02-23 10:42:48 +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
|
|
|
|
}
|
|
|
|
|
2022-04-30 12:31:23 +03:00
|
|
|
// 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()
|
|
|
|
}
|