2018-10-17 14:07:58 +03:00
|
|
|
use console::Term;
|
2018-05-31 16:00:01 +03:00
|
|
|
use std::cmp::{max, min};
|
2018-10-17 14:07:58 +03:00
|
|
|
use std::io::{self, Write};
|
2018-06-27 22:19:36 +03:00
|
|
|
use term_size;
|
|
|
|
|
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
|
2018-05-31 16:00:01 +03:00
|
|
|
|
|
|
|
|
pub struct Terminal {
|
2018-06-27 22:19:36 +03:00
|
|
|
width: Option<usize>,
|
|
|
|
|
stdout: StandardStream,
|
2018-05-31 16:00:01 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Terminal {
|
|
|
|
|
pub fn new() -> Self {
|
|
|
|
|
Self {
|
2018-06-27 22:19:36 +03:00
|
|
|
width: term_size::dimensions().map(|(w, _)| w),
|
|
|
|
|
stdout: StandardStream::stdout(ColorChoice::Auto),
|
2018-05-31 16:00:01 +03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-27 22:19:36 +03:00
|
|
|
pub fn print_separator<P: AsRef<str>>(&mut self, message: P) {
|
2018-05-31 16:00:01 +03:00
|
|
|
let message = message.as_ref();
|
2018-06-04 23:23:25 +03:00
|
|
|
match self.width {
|
|
|
|
|
Some(width) => {
|
2018-08-07 21:13:50 +03:00
|
|
|
let _ = self
|
|
|
|
|
.stdout
|
2018-06-27 22:19:36 +03:00
|
|
|
.set_color(ColorSpec::new().set_fg(Some(Color::White)).set_bold(true));
|
2018-07-10 07:29:41 +03:00
|
|
|
let _ = writeln!(
|
2018-06-27 22:19:36 +03:00
|
|
|
&mut self.stdout,
|
2018-07-10 07:29:41 +03:00
|
|
|
"\n―― {} {:―^border$}",
|
2018-06-25 21:21:34 +03:00
|
|
|
message,
|
|
|
|
|
"",
|
|
|
|
|
border = max(2, min(80, width as usize) - 3 - message.len())
|
|
|
|
|
);
|
2018-06-27 22:19:36 +03:00
|
|
|
let _ = self.stdout.reset();
|
|
|
|
|
let _ = self.stdout.flush();
|
2018-06-04 23:23:25 +03:00
|
|
|
}
|
|
|
|
|
None => {
|
2018-07-10 07:29:41 +03:00
|
|
|
let _ = writeln!(&mut self.stdout, "―― {} ――", message);
|
2018-05-31 16:00:01 +03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-06-03 16:43:53 +03:00
|
|
|
|
2018-06-27 23:04:39 +03:00
|
|
|
#[allow(dead_code)]
|
2018-06-27 22:19:36 +03:00
|
|
|
pub fn print_warning<P: AsRef<str>>(&mut self, message: P) {
|
2018-06-04 23:23:25 +03:00
|
|
|
let message = message.as_ref();
|
|
|
|
|
|
2018-08-07 21:13:50 +03:00
|
|
|
let _ = self
|
|
|
|
|
.stdout
|
2018-06-27 22:19:36 +03:00
|
|
|
.set_color(ColorSpec::new().set_fg(Some(Color::Yellow)).set_bold(true));
|
2018-07-10 07:29:41 +03:00
|
|
|
let _ = writeln!(&mut self.stdout, "{}", message);
|
2018-06-27 22:19:36 +03:00
|
|
|
let _ = self.stdout.reset();
|
|
|
|
|
let _ = self.stdout.flush();
|
2018-06-03 16:43:53 +03:00
|
|
|
}
|
2018-06-03 18:04:58 +03:00
|
|
|
|
2018-06-27 22:19:36 +03:00
|
|
|
pub fn print_result<P: AsRef<str>>(&mut self, key: P, succeeded: bool) {
|
2018-06-03 18:04:58 +03:00
|
|
|
let key = key.as_ref();
|
2018-06-27 22:19:36 +03:00
|
|
|
let _ = write!(&mut self.stdout, "{}: ", key);
|
2018-06-03 18:04:58 +03:00
|
|
|
|
2018-06-27 22:19:36 +03:00
|
|
|
let _ = self.stdout.set_color(
|
|
|
|
|
ColorSpec::new()
|
|
|
|
|
.set_fg(Some(if succeeded { Color::Green } else { Color::Red }))
|
|
|
|
|
.set_bold(true),
|
|
|
|
|
);
|
|
|
|
|
|
2018-07-10 07:29:41 +03:00
|
|
|
let _ = writeln!(&mut self.stdout, "{}", if succeeded { "OK" } else { "FAILED" });
|
2018-06-27 22:19:36 +03:00
|
|
|
|
|
|
|
|
let _ = self.stdout.reset();
|
|
|
|
|
let _ = self.stdout.flush();
|
2018-06-03 18:04:58 +03:00
|
|
|
}
|
2018-08-25 22:19:38 +03:00
|
|
|
|
2018-10-17 14:07:58 +03:00
|
|
|
pub fn should_retry(&mut self, running: bool) -> Result<bool, io::Error> {
|
2018-08-25 22:19:38 +03:00
|
|
|
if self.width.is_none() {
|
2018-10-17 14:07:58 +03:00
|
|
|
return Ok(false);
|
2018-08-25 22:19:38 +03:00
|
|
|
}
|
2018-10-17 14:07:58 +03:00
|
|
|
|
2018-09-06 15:17:03 +03:00
|
|
|
println!();
|
2018-08-25 22:19:38 +03:00
|
|
|
loop {
|
|
|
|
|
let _ = self
|
|
|
|
|
.stdout
|
|
|
|
|
.set_color(ColorSpec::new().set_fg(Some(Color::Yellow)).set_bold(true));
|
|
|
|
|
let _ = write!(&mut self.stdout, "Retry? [y/N] ");
|
2018-10-17 14:07:58 +03:00
|
|
|
if !running {
|
|
|
|
|
write!(&mut self.stdout, "(Press Ctrl+C again to stop Topgrade) ");
|
|
|
|
|
}
|
2018-08-25 22:19:38 +03:00
|
|
|
let _ = self.stdout.reset();
|
|
|
|
|
let _ = self.stdout.flush();
|
|
|
|
|
|
2018-10-17 14:07:58 +03:00
|
|
|
match Term::stdout().read_char()? {
|
|
|
|
|
'y' | 'Y' => return Ok(true),
|
|
|
|
|
'n' | 'N' | '\n' => return Ok(false),
|
|
|
|
|
_ => (),
|
2018-08-25 22:19:38 +03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-05-31 16:00:01 +03:00
|
|
|
}
|