From 65d6bba9254d514a16e0bf89d76cbd9b90740e5c Mon Sep 17 00:00:00 2001 From: Daniel Parks Date: Mon, 18 Nov 2019 01:26:20 -0800 Subject: [PATCH] api: fix for splitn("a", 2) returning extra "" Corrects `/-/.splitn("a", 2)` to return `["a"]` instead of `["a", ""]`. (`/-/` is shorthand for `Regex::new("-").unwrap()`.) Fixes #521, Closes #606, Closes #628 --- CHANGELOG.md | 4 +++- src/re_bytes.rs | 15 +++++++++++---- src/re_unicode.rs | 15 +++++++++++---- tests/api.rs | 4 +--- 4 files changed, 26 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index db36d21328..2606af8bd5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,10 +9,12 @@ New features: Bug fixes: +* [BUG #521](https://github.com/rust-lang/regex/issues/521): + Corrects `/-/.splitn("a", 2)` to return `["a"]` instead of `["a", ""]`. * [BUG #594](https://github.com/rust-lang/regex/pull/594): Improve error reporting when writing `\p\`. * [BUG #627](https://github.com/rust-lang/regex/issues/627): - Corrects `re.split("a-")` to return `["a", ""]` instead of `["a"]`. + Corrects `/-/.split("a-")` to return `["a", ""]` instead of `["a"]`. * [BUG #633](https://github.com/rust-lang/regex/pull/633): Squash deprecation warnings for the `std::error::Error::description` method. diff --git a/src/re_bytes.rs b/src/re_bytes.rs index dff70c0ba9..69f0b335de 100644 --- a/src/re_bytes.rs +++ b/src/re_bytes.rs @@ -774,12 +774,19 @@ impl<'r, 't> Iterator for SplitN<'r, 't> { if self.n == 0 { return None; } + self.n -= 1; - if self.n == 0 { - let text = self.splits.finder.0.text(); - Some(&text[self.splits.last..]) + if self.n > 0 { + return self.splits.next(); + } + + let text = self.splits.finder.0.text(); + if self.splits.last > text.len() { + // We've already returned all substrings. + None } else { - self.splits.next() + // self.n == 0, so future calls will return None immediately + Some(&text[self.splits.last..]) } } } diff --git a/src/re_unicode.rs b/src/re_unicode.rs index 7498757830..b746599088 100644 --- a/src/re_unicode.rs +++ b/src/re_unicode.rs @@ -814,12 +814,19 @@ impl<'r, 't> Iterator for SplitN<'r, 't> { if self.n == 0 { return None; } + self.n -= 1; - if self.n == 0 { - let text = self.splits.finder.0.text(); - Some(&text[self.splits.last..]) + if self.n > 0 { + return self.splits.next(); + } + + let text = self.splits.finder.0.text(); + if self.splits.last > text.len() { + // We've already returned all substrings. + None } else { - self.splits.next() + // self.n == 0, so future calls will return None immediately + Some(&text[self.splits.last..]) } } } diff --git a/tests/api.rs b/tests/api.rs index e16f7264bc..0d4962cc9f 100644 --- a/tests/api.rs +++ b/tests/api.rs @@ -213,9 +213,7 @@ split!(split_trailing_blank, r"-", r"a-", &[t!("a"), t!("")]); split!(split_trailing_blanks, r"-", r"a--", &[t!("a"), t!(""), t!("")]); split!(split_empty, r"-", r"", &[t!("")]); -// See: https://github.com/rust-lang/regex/issues/521 -// splitn!(splitn_below_limit, r"-", r"a", 2, &[t!("a")]); - +splitn!(splitn_below_limit, r"-", r"a", 2, &[t!("a")]); splitn!(splitn_at_limit, r"-", r"a-b", 2, &[t!("a"), t!("b")]); splitn!(splitn_above_limit, r"-", r"a-b-c", 2, &[t!("a"), t!("b-c")]); splitn!(splitn_zero_limit, r"-", r"a-b", 0, empty_vec!());