1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
//! A collection of convenience methods around loading files into various containers. //! //! This crate contains a few small wrapper methods around common operations in the standard //! library for loading files. The `Read` trait is a little cumbersome if you don't want to bother //! keeping up with a buffer, or if you're only loading one file. Here, you can wrap up all that //! boilerplate into little one-off functions! //! //! To read a file into a string: //! //! ```no_run //! let my_file = slurp::read_all_to_string("myfile.txt").unwrap(); //! ``` //! //! To read a file into a byte vector: //! //! ```no_run //! let my_file = slurp::read_all_bytes("myfile.txt").unwrap(); //! ``` //! //! Or, to read a file into a Vec where each element is a different line: //! //! ```no_run //! let my_file: Vec<String> = slurp::read_all_lines("myfile.txt").unwrap(); //! ``` //! //! There's also an iterator to lazily load the lines, though it's mainly a wrapper over //! `io::BufReader`: //! //! ```no_run //! for line in slurp::iterate_all_lines("myfile.txt") { //! let line = line.unwrap(); //! } //! ``` #![deny(warnings, missing_docs)] use std::io::{self, Read, BufRead}; use std::fs::File; use std::path::{Path, PathBuf}; /// Reads the file at the given filename into a new String. pub fn read_all_to_string<P: AsRef<Path>>(filename: P) -> io::Result<String> { let mut out = String::new(); let mut file = File::open(filename)?; file.read_to_string(&mut out)?; Ok(out) } /// Reads the file at the given filename into a new byte vector. pub fn read_all_bytes<P: AsRef<Path>>(filename: P) -> io::Result<Vec<u8>> { let mut out = Vec::new(); let mut file = File::open(filename)?; file.read_to_end(&mut out)?; Ok(out) } /// Returns an iterator over the lines in the file at the given filename. /// /// Note that this iterator lazily opens the file - it won't touch the filesystem until you start /// iterating. pub fn iterate_all_lines<P: AsRef<Path>>(filename: P) -> Lines { Lines { filename: filename.as_ref().to_path_buf(), iter: None, } } /// Reads the lines of the file at the given filename into a new collection of Strings. pub fn read_all_lines<P: AsRef<Path>>(filename: P) -> io::Result<Vec<String>> { iterate_all_lines(filename).collect() } /// Iterator over the lines of a file. /// /// See [`iterate_all_lines`] for details. /// /// [`iterate_all_lines`]: fn.iterate_all_lines.html #[must_use = "iterators are lazy and do nothing unless consumed"] pub struct Lines { filename: PathBuf, iter: Option<io::Lines<io::BufReader<File>>>, } impl Iterator for Lines { type Item = io::Result<String>; fn next(&mut self) -> Option<Self::Item> { if self.iter.is_none() { match File::open(&self.filename) { Ok(f) => self.iter = Some(io::BufReader::new(f).lines()), Err(e) => return Some(Err(e)), } } self.iter.as_mut().and_then(|i| i.next()) } }