Skip to main content

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