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
//! Provides the higher order `IO` function [`interact`](crate::interact) for prototyping command line interfaces. //! //! *A small tutorial package for Haskell refugees adapted from this lovely [walkthrough](https://wiki.haskell.org/Tutorials/Programming_Haskell/String_IO#IO).* //! //! Interact takes a function of type `Fn(String) -> String`, runs it on `stdin` //! and prints the result to `stdout`. //! //! # Examples //! ## `cat` //! ``` //! use interakt::interact; //! use std::convert::identity; //! //! fn main() -> std::io::Result<()> { interact(identity) } //! ``` //! ```shell //! $ cat cat.rs | cargo run --bin cat //! use interakt::interact; //! use std::convert::identity; //! //! fn main() -> std::io::Result<()> { interact(identity) } //! ``` //! ## `wc` //! ``` //! # use interakt::interact; //! fn main() -> std::io::Result<()> { //! let count = |s: String| -> String { format!("{}\n", s.len()) }; //! interact(count) //! } //! ``` //! ```shell //! $ cat cat.rs | cargo run --bin wc //! 109 //! ``` //! ## `wc -l` //! ``` //! # use interakt::interact; //! fn main() -> std::io::Result<()> { //! let count_lines = |s: String| -> String { //! format!("{}\n", s.lines().collect::<Vec<_>>().len()) //! }; //! interact(count_lines) //! } //! ``` //! ```shell //! $ cat cat.rs | cargo run --bin wcl //! 4 //! ``` //! ## `rev` //! ``` //! # use interakt::interact; //! fn main() -> std::io::Result<()> { //! let rev_lines = |s: String| -> String { //! s.lines() //! .map(|line| line.chars().rev().collect()) //! .collect::<Vec<String>>() //! .join("\n") //! }; //! interact(rev_lines) //! } //! ``` //! ```text //! $ cat cat.rs | cargo run --bin rev //! ;tcaretni::tkaretni esu //! ;ytitnedi::trevnoc::dts esu //! //! } )ytitnedi(tcaretni { >)(<tluseR::oi::dts >- )(niam nf //! ``` use std::io::{Read, Write}; /// The higher-order `interact` function. /// /// In Haskell, the interact function is: /// ```text /// interact f = do s <- getContents /// putStr (f s) /// ``` pub fn interact<F>(f: F) -> std::io::Result<()> where F: std::ops::Fn(String) -> String { let mut buffer = String::new(); std::io::stdin().read_to_string(&mut buffer)?; std::io::stdout().write_all(f(buffer).as_bytes())?; Ok(()) } #[cfg(test)] mod tests { #[test] fn it_works() { assert_eq!(2 + 2, 4); } }