iterate_text/file/lines.rs
1#!/usr/bin/env rust
2
3
4//! Reads from file path, buffer, or descriptor and iterates over lines until EOF is reached
5//!
6//! # Example
7//!
8//! ```rust
9//! use iterate_text::file::lines::IterateFileLines;
10//!
11//! let p = "tests/file/lines/file.txt";
12//! let mut l = IterateFileLines::new(p);
13//!
14//! assert_eq!(l.next(), Some("First line\n".to_string()));
15//! assert_eq!(l.next(), Some("Second line\n".to_string()));
16//! assert_eq!(l.next(), Some("Third line\n".to_string()));
17//! assert_eq!(l.next(), None);
18//! ```
19
20
21use std::io::BufReader;
22use std::io::BufRead;
23use std::fs::File;
24
25
26/// Wraps `BufReader<File>` and wraps `.read_line()` from `BufReader` as an Iterator
27#[derive(Debug)]
28pub struct IterateFileLines {
29 file_buffer: BufReader<File>,
30}
31
32
33impl IterateFileLines {
34 /// Initializes structure with `BufReader` for file `path`
35 pub fn new<S: Into<String>>(path: S) -> Self {
36 let file_descriptor = File::open(path.into()).unwrap();
37 let file_buffer = BufReader::new(file_descriptor);
38 Self { file_buffer }
39 }
40}
41
42
43impl Iterator for IterateFileLines {
44 type Item = String;
45
46 /// Returns `Option<String>` when a line is available from `.read_line()` or `None` when EOF is
47 /// reached.
48 fn next(&mut self) -> Option<Self::Item> {
49 let mut line = String::new();
50 match self.file_buffer.read_line(&mut line) {
51 Ok(state) => match state {
52 0 => None,
53 _ => Some(line),
54 },
55 _ => None,
56 }
57 }
58}
59
60
61impl From<File> for IterateFileLines {
62 /// Initializes structure from `File` descriptor
63 fn from (file_descriptor: File) -> Self {
64 Self { file_buffer: BufReader::new(file_descriptor) }
65 }
66}
67
68impl From<BufReader<File>> for IterateFileLines {
69 /// Initializes structure from `BufReader<File>`
70 fn from(buffer_reader: BufReader<File>) -> Self {
71 Self { file_buffer: buffer_reader }
72 }
73}
74