Rollup merge of #100311 - xfix:lines-fix-handling-of-bare-cr, r=ChrisDenton
Fix handling of trailing bare CR in str::lines Continuing from #91191. Fixes #94435.
This commit is contained in:
commit
d694f47baa
@ -1499,13 +1499,25 @@ fn test_split_whitespace() {
|
||||
|
||||
#[test]
|
||||
fn test_lines() {
|
||||
let data = "\nMäry häd ä little lämb\n\r\nLittle lämb\n";
|
||||
let lines: Vec<&str> = data.lines().collect();
|
||||
assert_eq!(lines, ["", "Märy häd ä little lämb", "", "Little lämb"]);
|
||||
|
||||
let data = "\r\nMäry häd ä little lämb\n\nLittle lämb"; // no trailing \n
|
||||
let lines: Vec<&str> = data.lines().collect();
|
||||
assert_eq!(lines, ["", "Märy häd ä little lämb", "", "Little lämb"]);
|
||||
fn t(data: &str, expected: &[&str]) {
|
||||
let lines: Vec<&str> = data.lines().collect();
|
||||
assert_eq!(lines, expected);
|
||||
}
|
||||
t("", &[]);
|
||||
t("\n", &[""]);
|
||||
t("\n2nd", &["", "2nd"]);
|
||||
t("\r\n", &[""]);
|
||||
t("bare\r", &["bare\r"]);
|
||||
t("bare\rcr", &["bare\rcr"]);
|
||||
t("Text\n\r", &["Text", "\r"]);
|
||||
t(
|
||||
"\nMäry häd ä little lämb\n\r\nLittle lämb\n",
|
||||
&["", "Märy häd ä little lämb", "", "Little lämb"],
|
||||
);
|
||||
t(
|
||||
"\r\nMäry häd ä little lämb\n\nLittle lämb",
|
||||
&["", "Märy häd ä little lämb", "", "Little lämb"],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -13,7 +13,7 @@
|
||||
use super::pattern::Pattern;
|
||||
use super::pattern::{DoubleEndedSearcher, ReverseSearcher, Searcher};
|
||||
use super::validations::{next_code_point, next_code_point_reverse};
|
||||
use super::LinesAnyMap;
|
||||
use super::LinesMap;
|
||||
use super::{BytesIsNotEmpty, UnsafeBytesToStr};
|
||||
use super::{CharEscapeDebugContinue, CharEscapeDefault, CharEscapeUnicode};
|
||||
use super::{IsAsciiWhitespace, IsNotEmpty, IsWhitespace};
|
||||
@ -1104,7 +1104,7 @@ fn next_back(&mut self) -> Option<&'a str>
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[must_use = "iterators are lazy and do nothing unless consumed"]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Lines<'a>(pub(super) Map<SplitTerminator<'a, char>, LinesAnyMap>);
|
||||
pub struct Lines<'a>(pub(super) Map<SplitInclusive<'a, char>, LinesMap>);
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<'a> Iterator for Lines<'a> {
|
||||
|
@ -1011,7 +1011,7 @@ pub fn split_ascii_whitespace(&self) -> SplitAsciiWhitespace<'_> {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn lines(&self) -> Lines<'_> {
|
||||
Lines(self.split_terminator('\n').map(LinesAnyMap))
|
||||
Lines(self.split_inclusive('\n').map(LinesMap))
|
||||
}
|
||||
|
||||
/// An iterator over the lines of a string.
|
||||
@ -2604,10 +2604,10 @@ fn default() -> Self {
|
||||
impl_fn_for_zst! {
|
||||
/// A nameable, cloneable fn type
|
||||
#[derive(Clone)]
|
||||
struct LinesAnyMap impl<'a> Fn = |line: &'a str| -> &'a str {
|
||||
let l = line.len();
|
||||
if l > 0 && line.as_bytes()[l - 1] == b'\r' { &line[0 .. l - 1] }
|
||||
else { line }
|
||||
struct LinesMap impl<'a> Fn = |line: &'a str| -> &'a str {
|
||||
let Some(line) = line.strip_suffix('\n') else { return line };
|
||||
let Some(line) = line.strip_suffix('\r') else { return line };
|
||||
line
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
|
Loading…
Reference in New Issue
Block a user