Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix 337: Look ahead for b' ' if skip_initial_space is enabled #366

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions csv-core/src/reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ pub struct Reader {
has_read: bool,
/// The current position in the output buffer when reading a record.
output_pos: usize,
/// Skip any space following the delimiter
skip_initial_space: bool,
}

impl Default for Reader {
Expand All @@ -145,6 +147,7 @@ impl Default for Reader {
line: 1,
has_read: false,
output_pos: 0,
skip_initial_space: false,
}
}
}
Expand Down Expand Up @@ -256,6 +259,15 @@ impl ReaderBuilder {
self.rdr.use_nfa = yes;
self
}

/// Enable or disable initial space.
///
/// When enabled skip any space following the field delimiter when
/// parsing CSV.
pub fn skip_initial_space(&mut self, yes: bool) -> &mut ReaderBuilder {
self.rdr.skip_initial_space = yes;
self
}
}

/// The result of parsing at most one field from CSV data.
Expand Down Expand Up @@ -671,6 +683,12 @@ impl Reader {
if has_out {
output[nout] = input[nin];
nout += 1;
} else if self.skip_initial_space
&& nin < input.len() - 1
&& input[nin] == self.delimiter
&& input[nin + 1] == b' '
{
nin += 1;
}
nin += 1;
if state >= self.dfa.final_field {
Expand Down Expand Up @@ -731,6 +749,12 @@ impl Reader {
if has_out {
output[nout] = b;
nout += 1;
} else if self.skip_initial_space
&& nin < input.len() - 1
&& input[nin] == self.delimiter
&& input[nin + 1] == b' '
{
nin += 1;
}
nin += 1;
if state >= self.dfa.final_field {
Expand Down Expand Up @@ -893,6 +917,12 @@ impl Reader {
nin += 1;
}
NfaInputAction::Discard => {
if self.skip_initial_space
&& nin < input.len() - 1
&& input[nin + 1] == b' '
{
nin += 1;
}
nin += 1;
}
NfaInputAction::Epsilon => {}
Expand Down Expand Up @@ -944,6 +974,12 @@ impl Reader {
nin += 1;
}
NfaInputAction::Discard => {
if self.skip_initial_space
&& nin < input.len() - 1
&& input[nin + 1] == b' '
{
nin += 1;
}
nin += 1;
}
NfaInputAction::Epsilon => (),
Expand Down Expand Up @@ -1725,6 +1761,14 @@ mod tests {
b.comment(Some(b'#'));
}
);
parses_to!(
issue_337,
"a, \"b\", c",
csv![["a", "b", "c"]],
|b: &mut ReaderBuilder| {
b.skip_initial_space(true);
}
);

macro_rules! assert_read {
(
Expand Down
9 changes: 9 additions & 0 deletions src/reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,15 @@ impl ReaderBuilder {
self.builder.nfa(yes);
self
}

/// Enable or disable initial space.
///
/// When enabled skip any space following the field delimiter when
/// parsing CSV.
pub fn skip_initial_space(&mut self, yes: bool) -> &mut ReaderBuilder {
self.builder.skip_initial_space(yes);
self
}
}

/// A already configured CSV reader.
Expand Down