1 //! # Terminal progress bar for Rust 2 //! 3 //! Console progress bar for Rust Inspired from [pb](http://github.com/cheggaaa/pb), support and 4 //! tested on MacOS, Linux and Windows 5 //! 6 //! ![Screenshot](https://raw.githubusercontent.com/a8m/pb/master/gif/rec_v3.gif) 7 //! 8 //! [Documentation](http://a8m.github.io/pb/doc/pbr/index.html) 9 //! 10 //! ### Examples 11 //! 1. simple example 12 //! 13 //! ```ignore 14 //! extern crate pbr; 15 //! 16 //! use pbr::ProgressBar; 17 //! use std::thread; 18 //! 19 //! fn main() { 20 //! let count = 1000; 21 //! let mut pb = ProgressBar::new(count); 22 //! pb.format("╢▌▌░╟"); 23 //! for _ in 0..count { 24 //! pb.inc(); 25 //! thread::sleep_ms(200); 26 //! } 27 //! pb.finish_print("done"); 28 //! } 29 //! ``` 30 //! 31 //! 2. MultiBar example. see full example [here](https://github.com/a8m/pb/blob/master/examples/multi.rs) 32 //! 33 //! ```ignore 34 //! extern crate pbr; 35 //! 36 //! use std::thread; 37 //! use pbr::MultiBar; 38 //! use std::time::Duration; 39 //! 40 //! fn main() { 41 //! let mut mb = MultiBar::new(); 42 //! let count = 100; 43 //! mb.println("Application header:"); 44 //! 45 //! let mut p1 = mb.create_bar(count); 46 //! let _ = thread::spawn(move || { 47 //! for _ in 0..count { 48 //! p1.inc(); 49 //! thread::sleep(Duration::from_millis(100)); 50 //! } 51 //! // notify the multibar that this bar finished. 52 //! p1.finish(); 53 //! }); 54 //! 55 //! mb.println("add a separator between the two bars"); 56 //! 57 //! let mut p2 = mb.create_bar(count * 2); 58 //! let _ = thread::spawn(move || { 59 //! for _ in 0..count * 2 { 60 //! p2.inc(); 61 //! thread::sleep(Duration::from_millis(100)); 62 //! } 63 //! // notify the multibar that this bar finished. 64 //! p2.finish(); 65 //! }); 66 //! 67 //! // start listen to all bars changes. 68 //! // this is a blocking operation, until all bars will finish. 69 //! // to ignore blocking, you can run it in a different thread. 70 //! mb.listen(); 71 //! } 72 //! ``` 73 //! 74 //! 3. Broadcast writing(simple file copying) 75 //! 76 //! ```ignore 77 //! #![feature(io)] 78 //! extern crate pbr; 79 //! 80 //! use std::io::copy; 81 //! use std::io::prelude::*; 82 //! use std::fs::File; 83 //! use pbr::{ProgressBar, Units}; 84 //! 85 //! fn main() { 86 //! let mut file = File::open("/usr/share/dict/words").unwrap(); 87 //! let n_bytes = file.metadata().unwrap().len() as usize; 88 //! let mut pb = ProgressBar::new(n_bytes); 89 //! pb.set_units(Units::Bytes); 90 //! let mut handle = File::create("copy-words").unwrap().broadcast(&mut pb); 91 //! copy(&mut file, &mut handle).unwrap(); 92 //! pb.finish_print("done"); 93 //! } 94 //! ``` 95 96 // Macro for writing to the giving writer. 97 // Used in both pb.rs and multi.rs modules. 98 // 99 // # Examples 100 // 101 // ``` 102 // let w = io::stdout(); 103 // printfl!(w, ""); 104 // printfl!(w, "\r{}", out); 105 // 106 // ``` 107 macro_rules! printfl { 108 ($w:expr, $($tt:tt)*) => {{ 109 $w.write(&format!($($tt)*).as_bytes()).ok().expect("write() fail"); 110 $w.flush().ok().expect("flush() fail"); 111 }} 112 } 113 114 extern crate crossbeam_channel; 115 extern crate time; 116 mod multi; 117 mod pb; 118 mod tty; 119 pub use multi::{MultiBar, Pipe}; 120 pub use pb::{ProgressBar, Units}; 121 use std::io::{stdout, Stdout, Write}; 122 123 pub struct PbIter<T, I> 124 where 125 I: Iterator, 126 T: Write, 127 { 128 iter: I, 129 progress_bar: ProgressBar<T>, 130 } 131 132 impl<I> PbIter<Stdout, I> 133 where 134 I: Iterator, 135 { new(iter: I) -> Self136 pub fn new(iter: I) -> Self { 137 Self::on(stdout(), iter) 138 } 139 } 140 141 impl<T, I> PbIter<T, I> 142 where 143 I: Iterator, 144 T: Write, 145 { on(handle: T, iter: I) -> Self146 pub fn on(handle: T, iter: I) -> Self { 147 let size = iter.size_hint().0; 148 PbIter { 149 iter: iter, 150 progress_bar: ProgressBar::on(handle, size as u64), 151 } 152 } 153 } 154 155 impl<T, I> Iterator for PbIter<T, I> 156 where 157 I: Iterator, 158 T: Write, 159 { 160 type Item = I::Item; 161 next(&mut self) -> Option<I::Item>162 fn next(&mut self) -> Option<I::Item> { 163 match self.iter.next() { 164 Some(i) => { 165 self.progress_bar.inc(); 166 Some(i) 167 } 168 None => None, 169 } 170 } 171 size_hint(&self) -> (usize, Option<usize>)172 fn size_hint(&self) -> (usize, Option<usize>) { 173 self.iter.size_hint() 174 } 175 } 176