I need to iterate over lines in a string, but keep the newlines at the end in the strings that are yielded.
There is str.lines()
, but the strings it returns have the newline characters chopped off:
let result: Vec<_> = "foo\nbar\n".lines().collect();
assert_eq!(result, vec!["foo", "bar"]);
Here's what I need:
assert_eq!(lines("foo\nbar\n"), vec!["foo\n", "bar\n"]);
More test cases:
assert!(lines("").is_empty());
assert_eq!(lines("f"), vec!["f"]);
assert_eq!(lines("foo"), vec!["foo"]);
assert_eq!(lines("foo\n"), vec!["foo\n"]);
assert_eq!(lines("foo\nbar"), vec!["foo\n", "bar"]);
assert_eq!(lines("foo\r\nbar"), vec!["foo\r\n", "bar"]);
assert_eq!(lines("foo\r\nbar\r\n"), vec!["foo\r\n", "bar\r\n"]);
assert_eq!(lines("\nfoo"), vec!["\n", "foo"]);
assert_eq!(lines("\n\n\n"), vec!["\n", "\n", "\n"]);
I have a solution that basically calls find
in a loop, but I'm wondering if there's something more elegant.
This is similar to Split a string keeping the separators, but in that case, the characters are returned as separate items, but I want to keep them as part of the string:
["hello\n", "world\n"]; // This
["hello", "\n", "world", "\n"]; // Not this
The solution I currently have looks like this: