Force progress bar to output to stderr even when not a terminal

This commit is contained in:
RunasSudo 2023-04-21 17:21:33 +10:00
parent 9893657bb0
commit f6f44c64ab
Signed by: RunasSudo
GPG Key ID: 7234E476BF21C61A
5 changed files with 82 additions and 5 deletions

1
Cargo.lock generated
View File

@ -312,6 +312,7 @@ name = "hpstat"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"clap", "clap",
"console",
"indicatif", "indicatif",
"nalgebra", "nalgebra",
"prettytable-rs", "prettytable-rs",

View File

@ -5,6 +5,7 @@ edition = "2021"
[dependencies] [dependencies]
clap = { version = "4.2.1", features = ["derive"] } clap = { version = "4.2.1", features = ["derive"] }
console = "0.15.5"
indicatif = {version = "0.17.3", features = ["rayon"]} indicatif = {version = "0.17.3", features = ["rayon"]}
nalgebra = "0.32.2" nalgebra = "0.32.2"
prettytable-rs = "0.10.0" prettytable-rs = "0.10.0"

View File

@ -20,12 +20,14 @@ use std::fs;
use std::io; use std::io;
use clap::{Args, ValueEnum}; use clap::{Args, ValueEnum};
use indicatif::{ParallelProgressIterator, ProgressBar, ProgressStyle}; use indicatif::{ParallelProgressIterator, ProgressBar, ProgressDrawTarget, ProgressStyle};
use nalgebra::{DMatrix, DVector, Matrix1xX}; use nalgebra::{DMatrix, DVector, Matrix1xX};
use prettytable::{Table, format, row}; use prettytable::{Table, format, row};
use rayon::prelude::*; use rayon::prelude::*;
use serde::{Serialize, Deserialize}; use serde::{Serialize, Deserialize};
use crate::term::UnconditionalTermLike;
#[derive(Args)] #[derive(Args)]
pub struct IntCoxArgs { pub struct IntCoxArgs {
/// Path to CSV input file containing the observations /// Path to CSV input file containing the observations
@ -98,10 +100,7 @@ pub fn main(args: IntCoxArgs) {
} }
// Fit regression // Fit regression
let progress_bar = match args.output { let progress_bar = ProgressBar::with_draw_target(Some(0), ProgressDrawTarget::term_like(Box::new(UnconditionalTermLike::stderr())));
OutputFormat::Text => ProgressBar::new(0),
OutputFormat::Json => ProgressBar::hidden(),
};
let result = fit_interval_censored_cox(data_times, data_indep, args.max_iterations, args.tolerance, args.reduced, progress_bar); let result = fit_interval_censored_cox(data_times, data_indep, args.max_iterations, args.tolerance, args.reduced, progress_bar);
// Display output // Display output

View File

@ -1 +1,3 @@
pub mod intcox; pub mod intcox;
mod term;

74
src/term.rs Normal file
View File

@ -0,0 +1,74 @@
// hpstat: High-performance statistics implementations
// Copyright © 2023 Lee Yingtong Li (RunasSudo)
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
use std::io;
use console::Term;
use indicatif::TermLike;
#[derive(Debug)]
pub struct UnconditionalTermLike {
term: Term
}
impl UnconditionalTermLike {
//pub fn new(term: Term) -> UnconditionalTermLike {
// return UnconditionalTermLike { term: term };
//}
pub fn stderr() -> UnconditionalTermLike {
return UnconditionalTermLike { term: Term::stderr() };
}
}
impl TermLike for UnconditionalTermLike {
fn width(&self) -> u16 {
return self.term.width();
}
fn move_cursor_up(&self, n: usize) -> io::Result<()> {
return self.term.move_cursor_up(n);
}
fn move_cursor_down(&self, n: usize) -> io::Result<()> {
return self.term.move_cursor_down(n);
}
fn move_cursor_right(&self, n: usize) -> io::Result<()> {
return self.term.move_cursor_right(n);
}
fn move_cursor_left(&self, n: usize) -> io::Result<()> {
return self.term.move_cursor_left(n);
}
fn write_line(&self, s: &str) -> io::Result<()> {
return self.term.write_line(s);
}
fn write_str(&self, s: &str) -> io::Result<()> {
return self.term.write_str(s);
}
fn clear_line(&self) -> io::Result<()> {
return self.term.clear_line();
}
fn flush(&self) -> io::Result<()> {
return self.term.flush();
}
}