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 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
//! Crate for reading whitespace-separated values. //! //! The crate defines a trait [`White`](trait.White.html), which //! describes types that can be parsed from whitespace-separated words, //! which includes eg. integers, tuples and vectors. //! //! The definition of whitespace used in this crate is described in //! [`SplitAsciiWhitespace`](stream/struct.SplitAsciiWhitespace.html). //! //! # Examples //! //! Basics //! //! ``` //! # use whiteread::parse_string; //! let (s, i): (String, i32) = parse_string(" answer 42 ").unwrap(); //! # assert!(s == "answer" && i == 42); //! ``` //! //! Easy reading from stdin. //! //! ```no_run //! # use whiteread::parse_line; //! let x: i32 = parse_line().unwrap(); //! ``` //! //! Efficient reading from stdin (newline-agnostic) with [`Reader`](struct.Reader.html). //! Stops on error. //! //! ```no_run //! # use whiteread::Reader; //! let i = std::io::stdin(); //! let mut i = Reader::new(i.lock()); //! while let Ok(f) = i.parse::<f64>() { //! println!("{}", f); //! } //! ``` //! //! If you want better error handling in while-let loops //! (stop on end of input, but propagate all the other errors), //! use [`none_on_too_short`](reader/trait.BorrowedResultExt.html#tymethod.none_on_too_short) use std::path::Path; use std::io; pub mod stream; pub mod white; pub use self::white::{White, Skip, SkipAll, Lengthed, Zeroed}; pub use self::white::{TooShort, ParseError, Leftovers}; pub mod reader; pub use self::reader::Reader; pub use self::reader::OwnedError as ReaderError; pub use self::reader::OwnedResult as ReaderResult; /// Reexports of traits containing the extension methods. /// /// The prelude is usually glob-imported: /// /// ``` /// use whiteread::prelude::*; /// ``` pub mod prelude { pub use super::reader::BorrowedResultExt; pub use super::reader::PrettyUnwrap; } // Helpers ----------------------------------------------------------------------------------------- /// Helper function for parsing `White` value from one line of stdin. /// /// Leftovers are considered an error. /// This function locks a mutex and allocates a buffer, so /// don't use it when reading more than few lines – /// use [`Reader`](struct.Reader.html) instead. /// /// # Examples /// ```no_run /// # use whiteread::parse_line; /// let x: i32 = parse_line().unwrap(); /// ``` pub fn parse_line<T: White>() -> white::Result<T> { let mut line = String::new(); io::stdin().read_line(&mut line)?; parse_string(&line) } /// Helper function for parsing `White` value from string. Leftovers are considered an error. /// /// # Examples /// ``` /// # use whiteread::parse_string; /// let number: i32 = parse_string(" 123 ").unwrap(); /// assert!(number == 123); /// ``` pub fn parse_string<T: White>(s: &str) -> white::Result<T> { let mut stream = stream::SplitAsciiWhitespace::new(s); let value = White::read(&mut stream)?; if let Ok(Some(_)) = stream::StrStream::next(&mut stream) { Err(Leftovers) } else { Ok(value) } } /// Parses a whole file as a `White` value /// /// Calling this function is equivalent to: /// /// ```no_run /// # use whiteread::{Reader, ReaderResult, White}; /// # fn foo<T: White>() -> ReaderResult<T> { /// # let path = "foo"; /// # Ok( /// Reader::open(path)?.finish()? /// # ) /// # } /// ``` /// /// If you want to parse the file in multiple steps, /// use [`Reader::open`](struct.Reader.html#method.open). /// /// # Examples /// /// Parse the whole file as an tuple. /// /// ```no_run /// # use whiteread::parse_file; /// let x: (i32, i32) = parse_file("coords.txt").unwrap(); /// ``` pub fn parse_file<T: White, P: AsRef<Path>>(path: P) -> ReaderResult<T> { Ok( Reader::open(path)?.finish()? ) }