-
-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Write output to stderr instead of stdout #1
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -95,32 +95,34 @@ | |
#![warn(missing_docs)] | ||
#![doc(html_root_url = "https://docs.rs/linya/0.1.0")] | ||
|
||
use std::io::{Stdout, Write}; | ||
use std::io::{LineWriter, Stderr, Write}; | ||
use terminal_size::{terminal_size, Height, Width}; | ||
|
||
/// A progress bar "coordinator" to share between threads. | ||
#[derive(Debug)] | ||
pub struct Progress { | ||
/// The drawable bars themselves. | ||
bars: Vec<SubBar>, | ||
/// A shared handle to `Stdout`, for buffer flushing. | ||
out: Stdout, | ||
/// A shared handle to `Stderr`. | ||
/// | ||
/// Line-buffered so that the cursor doesn't jump around unpleasantly. | ||
out: LineWriter<Stderr>, | ||
/// Terminal width and height. | ||
size: Option<(usize, usize)>, | ||
} | ||
|
||
impl Progress { | ||
/// Initialize a new progress bar coordinator. | ||
pub fn new() -> Progress { | ||
let out = std::io::stdout(); | ||
let out = LineWriter::new(std::io::stderr()); | ||
let bars = vec![]; | ||
let size = terminal_size().map(|(Width(w), Height(h))| (w as usize, h as usize)); | ||
Progress { bars, out, size } | ||
} | ||
|
||
/// Like [`Progress::new`] but accepts a size hint to avoid reallocation as bar count grows. | ||
pub fn with_capacity(capacity: usize) -> Progress { | ||
let out = std::io::stdout(); | ||
let out = LineWriter::new(std::io::stderr()); | ||
let bars = Vec::with_capacity(capacity); | ||
let size = terminal_size().map(|(Width(w), Height(h))| (w as usize, h as usize)); | ||
Progress { bars, out, size } | ||
|
@@ -139,14 +141,15 @@ impl Progress { | |
let label: String = label.into(); | ||
|
||
// An initial "empty" rendering of the new bar. | ||
println!( | ||
writeln!( | ||
&mut self.out, | ||
"{:<l$} [{:->f$}] 0%", | ||
label, | ||
"", | ||
l = twidth - w - 8 - 5, | ||
f = w | ||
); | ||
self.out.flush().unwrap(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since we call |
||
) | ||
.unwrap(); | ||
|
||
let bar = SubBar { | ||
curr: 0, | ||
|
@@ -187,7 +190,8 @@ impl Progress { | |
let diff = 100 * (b.curr - b.prev) / b.total; | ||
|
||
if b.cancelled { | ||
print!( | ||
write!( | ||
&mut self.out, | ||
"\x1B[s\x1B[{}A\r{:<l$} {:3}{} [{:_>f$}] ???%\x1B[u\r", | ||
pos, | ||
b.label, | ||
|
@@ -196,12 +200,14 @@ impl Progress { | |
"", | ||
l = term_width - w - 8 - 5, | ||
f = w, | ||
); | ||
) | ||
.unwrap(); | ||
|
||
// Very important, or the output won't appear fluid. | ||
self.out.flush().unwrap(); | ||
} else if b.curr >= b.total { | ||
print!( | ||
write!( | ||
&mut self.out, | ||
"\x1B[s\x1B[{}A\r{:<l$} {:3}{} [{:#>f$}] 100%\x1B[u\r", | ||
pos, | ||
b.label, | ||
|
@@ -210,14 +216,16 @@ impl Progress { | |
"", | ||
l = term_width - w - 8 - 5, | ||
f = w, | ||
); | ||
) | ||
.unwrap(); | ||
self.out.flush().unwrap(); | ||
} else if diff >= 1 { | ||
b.prev = b.curr; | ||
let f = (w * b.curr / b.total).min(w - 1); | ||
let e = (w - 1) - f; | ||
|
||
print!( | ||
write!( | ||
&mut self.out, | ||
"\x1B[s\x1B[{}A\r{:<l$} {:3}{} [{:#>f$}{}{:->e$}] {:3}%\x1B[u\r", | ||
pos, | ||
b.label, | ||
|
@@ -230,7 +238,8 @@ impl Progress { | |
l = term_width - w - 8 - 5, | ||
f = f, | ||
e = e | ||
); | ||
) | ||
.unwrap(); | ||
self.out.flush().unwrap(); | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These can stay as
println!
, they're just demos after all.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any reason to keep them that way?
eprintln
seems more consistent to me, but I'll defer to your judgement.