iterate_text/string/lines.rs
1#!/usr/bin/env rust
2
3
4//! Provides structure to iterate over lines within a string, or block of text, that includes
5//! new-line separators.
6//!
7//! > Depends on [IterateStringCharacters]
8//!
9//! # Example
10//!
11//! ```rust
12//! use iterate_text::string::lines::IterateStringLines;
13//!
14//! let s = String::from("This is\na \\n test string\n");
15//! let mut l = IterateStringLines::new(s);
16//!
17//! assert_eq!(l.next(), Some("This is\n".to_string()));
18//! assert_eq!(l.next(), Some("a \\n test string\n".to_string()));
19//! assert_eq!(l.next(), None);
20//! ```
21//!
22//! [IterateStringCharacters]: ../characters/index.html
23
24
25use crate::string::characters::IterateStringCharacters;
26
27
28/// Iterates over lines within string and includes new-line separator
29#[derive(Debug)]
30pub struct IterateStringLines {
31 iter: IterateStringCharacters,
32}
33
34
35impl IterateStringLines {
36 /// Passes ownership of `string` to instance of [`IterateStringCharacters`][IterateStringCharacters]
37 ///
38 /// [IterateStringCharacters]: ../characters/index.html
39 pub fn new<S>(string: S) -> Self
40 where
41 S: Into<String>
42 {
43 let iter = IterateStringCharacters::new(string);
44 Self { iter }
45 }
46}
47
48
49impl Iterator for IterateStringLines {
50 type Item = String;
51
52 /// Builds and returns `String` by consuming characters from [`IterateStringCharacters`][IterateStringCharacters] instance
53 ///
54 /// > Note, escaped newline characters (`\\n`) _should_ be ignored and preserved correctly
55 /// > during parsing
56 ///
57 /// [IterateStringCharacters]: ../characters/index.html
58 fn next(&mut self) -> Option<Self::Item> {
59 let mut line = String::new();
60 let mut escape = false;
61 loop {
62 if let Some(character) = self.iter.next() {
63 line.push(character);
64 match character {
65 '\\' => escape = true,
66 _ => {
67 if escape {
68 escape = false;
69 } else if character == '\n' {
70 return Some(line);
71 }
72 },
73 };
74 } else if !line.is_empty() {
75 return Some(line);
76 } else {
77 return None;
78 }
79
80 }
81 }
82}
83