Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ version = "0.1"
[dependencies.nitrokey]
version = "0.7.1"

[dependencies.progressing]
version = "3.0.2"

[dependencies.serde]
version = "1.0"
features = ["derive"]
Expand Down
17 changes: 8 additions & 9 deletions src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use nitrokey::GetPasswordSafe;

use crate::args;
use crate::config;
use crate::output;
use crate::pinentry;
use crate::Context;

Expand Down Expand Up @@ -474,22 +475,20 @@ pub fn fill(ctx: &mut Context<'_>) -> anyhow::Result<()> {
device.fill_sd_card(&pin).context("Failed to fill SD card")
})?;

let mut last_progress = 0;
loop {
let mut progress_bar = output::ProgressBar::new();
progress_bar.draw(ctx)?;
while !progress_bar.is_finished() {
use nitrokey::OperationStatus;

thread::sleep(time::Duration::from_secs(1));
let status = device
.get_operation_status()
.context("Failed to query operation status")?;
match status {
OperationStatus::Ongoing(progress) => {
if last_progress != progress {
println!(ctx, "{}/100", progress)?;
}
last_progress = progress;
}
OperationStatus::Idle => break,
OperationStatus::Ongoing(progress) => progress_bar.update(progress)?,
OperationStatus::Idle => progress_bar.finish(),
};
progress_bar.draw(ctx)?;
}

Ok(())
Expand Down
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ mod arg_util;
mod args;
mod commands;
mod config;
mod output;
mod pinentry;
#[cfg(test)]
mod tests;
Expand Down
82 changes: 82 additions & 0 deletions src/output.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// commands.rs

// Copyright (C) 2020 The Nitrocli Developers
// SPDX-License-Identifier: GPL-3.0-or-later

use crate::Context;

/// A progress bar that can be printed to an interactive output.
pub struct ProgressBar {
redraw: bool,
progress: u8,
toggle: bool,
finished: bool,
Comment thread
robinkrahl marked this conversation as resolved.
}

impl ProgressBar {
pub fn new() -> ProgressBar {
ProgressBar {
redraw: true,
progress: 0,
toggle: false,
finished: false,
}
}

pub fn is_finished(&self) -> bool {
self.finished
}

pub fn update(&mut self, progress: u8) -> anyhow::Result<()> {
anyhow::ensure!(!self.finished, "Tried to update finished progress bar");
anyhow::ensure!(
progress <= 100,
"Progress bar value out of range: {}",
progress
);
if progress != self.progress {
self.redraw = true;
self.progress = progress;
}
self.toggle = !self.toggle;
Ok(())
}

pub fn finish(&mut self) {
self.finished = true;
self.redraw = true;
self.progress = 100;
}

pub fn draw(&self, ctx: &mut Context<'_>) -> anyhow::Result<()> {
use crossterm::{cursor, terminal};
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh...guess we need it for other stuff too :-|

Have you considered using termion? Would it fulfill our requirements?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. termion works for ANSI terminals only. crossterm is cross-platform and also supports e. g. Windows terminals.


if !ctx.is_tty {
return Ok(());
}

let progress_char = if self.toggle && !self.finished {
"."
} else {
" "
};
if self.redraw {
use progressing::Baring;

let mut progress_bar = progressing::mapping::Bar::with_range(0, 100);
progress_bar.set(self.progress);

print!(ctx, "{}", terminal::Clear(terminal::ClearType::CurrentLine))?;
print!(ctx, "{}", cursor::MoveToColumn(0))?;
print!(ctx, " {} {}", progress_char, progress_bar)?;
if self.finished {
println!(ctx)?;
}
} else {
print!(ctx, "{}{}", cursor::MoveToColumn(1), progress_char)?;
}

ctx.stdout.flush()?;
Ok(())
}
}
6 changes: 6 additions & 0 deletions src/redefine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ macro_rules! println {
};
}

macro_rules! print {
($ctx:expr, $($arg:tt)*) => {
write!($ctx.stdout, $($arg)*)
};
}

macro_rules! eprintln {
($ctx:expr) => {
writeln!($ctx.stderr, "")
Expand Down