-
Notifications
You must be signed in to change notification settings - Fork 141
Expand file tree
/
Copy pathcsv.rs
More file actions
164 lines (143 loc) · 4.39 KB
/
Copy pathcsv.rs
File metadata and controls
164 lines (143 loc) · 4.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
use std::fmt::Debug;
use serde::{Deserialize, Serialize};
use utoipa::ToSchema;
/// Whitespace trimming policy applied to CSV fields or header names.
#[derive(Clone, Debug, Default, Deserialize, Serialize, ToSchema, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum CsvTrim {
/// Do not trim whitespace (default).
#[default]
None,
/// Trim whitespace from header names only.
Headers,
/// Trim whitespace from field values only.
Fields,
/// Trim whitespace from both header names and field values.
All,
}
#[derive(Clone, Debug, Deserialize, Serialize, ToSchema, PartialEq)]
#[serde(default)]
pub struct CsvFormatConfig {
/// Field delimiter (default `','`).
///
/// Must be an ASCII character.
///
/// Used by: input and output.
pub delimiter: char,
/// Whether the input begins with a header line (which is skipped).
///
/// Used by: input only.
pub headers: bool,
/// The quote character (default `'"'`).
///
/// Must be an ASCII character. Set `quoting` to `false` to disable
/// quoting entirely.
///
/// Used by: input only.
pub quote: char,
/// The escape character for quoted fields (default: `None`).
///
/// When `None` (the default), the CSV parser uses the double-quote
/// convention: a literal quote inside a quoted field is written as two
/// consecutive quote characters. When set, the given character is used
/// as the escape prefix instead (e.g. `Some('\\')` for backslash
/// escaping).
///
/// Must be an ASCII character.
///
/// Used by: input only.
pub escape: Option<char>,
/// Enable double-quote escaping (default `true`).
///
/// When `true`, a quote character inside a quoted field may be escaped by
/// doubling it. Setting this to `false` disables double-quote escaping
/// (an explicit `escape` character can still be used).
///
/// Used by: input only.
pub double_quote: bool,
/// Enable quoting (default `true`).
///
/// When `false`, the `quote` and `escape` characters have no special
/// meaning and every newline terminates a record regardless of context.
///
/// Used by: input only.
pub quoting: bool,
/// Comment character (default: `None`).
///
/// When set, lines whose first byte matches this character are treated as
/// comments and skipped entirely. Must be an ASCII character.
///
/// Used by: input only.
pub comment: Option<char>,
/// Allow records with a variable number of fields (default `true`).
///
/// When `true`, records that have fewer or more fields than expected are
/// accepted rather than treated as errors.
///
/// Used by: input only.
pub flexible: bool,
/// Whitespace trimming policy (default [`CsvTrim::None`]).
///
/// Used by: input only.
pub trim: CsvTrim,
}
impl CsvFormatConfig {
pub fn delimiter(&self) -> CsvDelimiter {
self.delimiter.into()
}
}
impl Default for CsvFormatConfig {
fn default() -> Self {
Self {
delimiter: CsvDelimiter::default().0.into(),
headers: false,
quote: '"',
escape: None,
double_quote: true,
quoting: true,
comment: None,
flexible: true,
trim: CsvTrim::None,
}
}
}
/// A delimiter between CSV records, typically `b','`.
#[derive(Copy, Clone)]
pub struct CsvDelimiter(pub u8);
impl CsvDelimiter {
pub const DEFAULT: CsvDelimiter = CsvDelimiter(b',');
}
impl Default for CsvDelimiter {
fn default() -> Self {
Self::DEFAULT
}
}
impl Debug for CsvDelimiter {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("CsvDelimiter")
.field(&char::from(self.0))
.finish()
}
}
impl From<char> for CsvDelimiter {
fn from(value: char) -> Self {
Self(value.try_into().unwrap_or(b','))
}
}
#[derive(Debug, Deserialize, Serialize, ToSchema)]
#[serde(default)]
pub struct CsvEncoderConfig {
/// Field delimiter (default `','`).
///
/// This must be an ASCII character.
pub delimiter: char,
pub buffer_size_records: usize,
}
impl Default for CsvEncoderConfig {
fn default() -> Self {
Self {
delimiter: CsvDelimiter::default().0.into(),
buffer_size_records: 10_000,
}
}
}