v / vlib / encoding / csv / writer.v
90 lines · 82 sloc · 1.8 KB · 8e35f4d9848f7ad35d857a187dddbfd2eca5e19d
Raw
1// Copyright (c) 2019-2024 Alexander Medvednikov. All rights reserved.
2// Use of this source code is governed by an MIT license
3// that can be found in the LICENSE file.
4module csv
5
6import strings
7
8struct Writer {
9 use_crlf bool
10 delimiter u8
11mut:
12 sb strings.Builder
13}
14
15@[params]
16pub struct WriterConfig {
17pub:
18 use_crlf bool
19 delimiter u8 = `,`
20}
21
22// new_writer returns a reference to a Writer
23pub fn new_writer(config WriterConfig) &Writer {
24 return &Writer{
25 sb: strings.new_builder(200)
26 use_crlf: config.use_crlf
27 delimiter: config.delimiter
28 }
29}
30
31// write writes a single record
32pub fn (mut w Writer) write(record []string) !bool {
33 if !valid_delim(w.delimiter) {
34 return &InvalidDelimiterError{}
35 }
36 le := if w.use_crlf { '\r\n' } else { '\n' }
37 for n, field_ in record {
38 mut field := field_
39 if n > 0 {
40 w.sb.write_string(w.delimiter.ascii_str())
41 }
42 if !w.field_needs_quotes(field) {
43 w.sb.write_string(field)
44 continue
45 }
46 w.sb.write_string('"')
47 for field.len > 0 {
48 mut i := field.index_any('"\r\n')
49 if i < 0 {
50 i = field.len
51 }
52 w.sb.write_string(field[..i])
53 field = field[i..]
54 if field.len > 0 {
55 z := field[0]
56 match z {
57 `"` { w.sb.write_string('""') }
58 `\r`, `\n` { w.sb.write_string(le) }
59 else {}
60 }
61
62 field = field[1..]
63 }
64 }
65 w.sb.write_string('"')
66 }
67 w.sb.write_string(le)
68 return true
69}
70
71// Once we have multi dimensional array
72// pub fn (w &Writer) write_all(records [][]string) {
73// for _, record in records {
74// w.write(record)
75// }
76// }
77fn (w &Writer) field_needs_quotes(field string) bool {
78 if field == '' {
79 return false
80 }
81 if field.contains(w.delimiter.ascii_str()) || field.index_any('"\r\n') != -1 {
82 return true
83 }
84 return false
85}
86
87// str returns the writer contents
88pub fn (mut w Writer) str() string {
89 return w.sb.str()
90}
91