feat: v0.4.0, add progress bar

This commit is contained in:
2023-10-15 17:56:23 +08:00
parent 6f70e7c83e
commit cb72baebee
6 changed files with 197 additions and 41 deletions

View File

@@ -7,7 +7,7 @@ use clap::Args;
use openpgp_card::crypto_data::Cryptogram;
use rust_util::{
debugging, failure, iff, information, opt_result, simple_error, success,
util_msg, warning, XResult,
warning, XResult,
};
use rust_util::util_time::UnixEpochTime;
use x509_parser::prelude::FromDer;
@@ -25,6 +25,7 @@ use crate::consts::{
};
use crate::crypto_aes::{aes_gcm_decrypt, try_aes_gcm_decrypt_with_salt};
use crate::spec::{EncEncryptedMeta, TinyEncryptEnvelop, TinyEncryptEnvelopType, TinyEncryptMeta};
use crate::util_process::Progress;
use crate::wrap_key::WrapKey;
#[derive(Debug, Args)]
@@ -115,14 +116,13 @@ pub fn decrypt_single(config: &Option<TinyEncryptConfig>,
} else {
let compressed_desc = iff!(meta.compress, " [compressed]", "");
let start = Instant::now();
util_msg::print_lastline(
&format!("Decrypting file: {}{} ...", path_display, compressed_desc)
);
let mut file_out = File::create(path_out)?;
let _ = decrypt_file(&mut file_in, &mut file_out, &key, &nonce, meta.compress)?;
let _ = decrypt_file(
&mut file_in, meta.file_length, &mut file_out,
&key, &nonce, meta.compress,
)?;
drop(file_out);
util_msg::clear_lastline();
util_file::update_out_file_time(enc_meta, path_out);
let encrypt_duration = start.elapsed();
@@ -136,10 +136,11 @@ pub fn decrypt_single(config: &Option<TinyEncryptConfig>,
Ok(meta.file_length)
}
fn decrypt_file(file_in: &mut File, file_out: &mut File, key: &[u8], nonce: &[u8], compress: bool) -> XResult<usize> {
let mut total_len = 0;
fn decrypt_file(file_in: &mut File, file_len: u64, file_out: &mut File, key: &[u8], nonce: &[u8], compress: bool) -> XResult<u64> {
let mut total_len = 0_u64;
let mut buffer = [0u8; 1024 * 8];
let key = opt_result!(key.try_into(), "Key is not 32 bytes: {}");
let progress = Progress::new(file_len);
let mut decryptor = aes_gcm_stream::Aes256GcmStreamDecryptor::new(key, nonce);
let mut gz_decoder = GzStreamDecoder::new();
loop {
@@ -156,9 +157,10 @@ fn decrypt_file(file_in: &mut File, file_out: &mut File, key: &[u8], nonce: &[u8
};
opt_result!(file_out.write_all(&last_block), "Write file failed: {}");
debugging!("Decrypt finished, total bytes: {}", total_len);
progress.finish();
break;
} else {
total_len += len;
total_len += len as u64;
let decrypted = decryptor.update(&buffer[0..len]);
let decrypted = if compress {
opt_result!(gz_decoder.update(&decrypted), "Decompress file failed: {}")
@@ -166,6 +168,7 @@ fn decrypt_file(file_in: &mut File, file_out: &mut File, key: &[u8], nonce: &[u8
decrypted
};
opt_result!(file_out.write_all(&decrypted), "Write file failed: {}");
progress.position(total_len);
}
}
let mut key = key;

View File

@@ -7,7 +7,7 @@ use std::time::Instant;
use clap::Args;
use flate2::Compression;
use rsa::Pkcs1v15Encrypt;
use rust_util::{debugging, failure, iff, information, opt_result, simple_error, success, util_msg, XResult};
use rust_util::{debugging, failure, iff, information, opt_result, simple_error, success, XResult};
use rust_util::util_time::UnixEpochTime;
use zeroize::Zeroize;
@@ -18,6 +18,7 @@ use crate::consts::{ENC_AES256_GCM_P256, ENC_AES256_GCM_P384, ENC_AES256_GCM_X25
use crate::crypto_aes::{aes_gcm_encrypt, aes_gcm_encrypt_with_salt};
use crate::crypto_rsa::parse_spki;
use crate::spec::{EncEncryptedMeta, EncMetadata, TINY_ENCRYPT_VERSION_10, TinyEncryptEnvelop, TinyEncryptEnvelopType, TinyEncryptMeta};
use crate::util_process::Progress;
use crate::wrap_key::{WrapKey, WrapKeyHeader};
#[derive(Debug, Args)]
@@ -153,11 +154,10 @@ fn encrypt_single(path: &PathBuf, envelops: &[&TinyEncryptConfigEnvelop], cmd_en
let compress_desc = iff!(cmd_encrypt.compress, " [with compress]", "");
let start = Instant::now();
util_msg::print_lastline(
&format!("Encrypting file: {}{} ...", path_display, compress_desc)
);
encrypt_file(&mut file_in, &mut file_out, &key, &nonce, cmd_encrypt.compress, &cmd_encrypt.compress_level)?;
util_msg::clear_lastline();
encrypt_file(
&mut file_in, file_metadata.len(), &mut file_out,
&key, &nonce, cmd_encrypt.compress, &cmd_encrypt.compress_level,
)?;
let encrypt_duration = start.elapsed();
debugging!("Inner encrypt file{}: {} elapsed: {} ms", compress_desc, path_display, encrypt_duration.as_millis());
@@ -194,8 +194,8 @@ fn process_compatible_with_1_0(cmd_encrypt: &CmdEncrypt, mut encrypt_meta: TinyE
Ok(encrypt_meta)
}
fn encrypt_file(file_in: &mut File, file_out: &mut File, key: &[u8], nonce: &[u8], compress: bool, compress_level: &Option<u32>) -> XResult<usize> {
let mut total_len = 0;
fn encrypt_file(file_in: &mut File, file_len: u64, file_out: &mut File, key: &[u8], nonce: &[u8], compress: bool, compress_level: &Option<u32>) -> XResult<u64> {
let mut total_len = 0_u64;
let mut buffer = [0u8; 1024 * 8];
let key = opt_result!(key.try_into(), "Key is not 32 bytes: {}");
let mut gz_encoder = match compress_level {
@@ -207,6 +207,7 @@ fn encrypt_file(file_in: &mut File, file_out: &mut File, key: &[u8], nonce: &[u8
GzStreamEncoder::new(Compression::new(*compress_level))
}
};
let progress = Progress::new(file_len);
let mut encryptor = aes_gcm_stream::Aes256GcmStreamEncryptor::new(key, nonce);
loop {
let len = opt_result!(file_in.read(&mut buffer), "Read file failed: {}");
@@ -225,9 +226,10 @@ fn encrypt_file(file_in: &mut File, file_out: &mut File, key: &[u8], nonce: &[u8
};
opt_result!(file_out.write_all(&last_block), "Write file failed: {}");
debugging!("Encrypt finished, total bytes: {}", total_len);
progress.finish();
break;
} else {
total_len += len;
total_len += len as u64;
let encrypted = if compress {
let compressed = opt_result!(gz_encoder.update(&buffer[0..len]), "Decompress file failed: {}");
encryptor.update(&compressed)
@@ -235,6 +237,7 @@ fn encrypt_file(file_in: &mut File, file_out: &mut File, key: &[u8], nonce: &[u8
encryptor.update(&buffer[0..len])
};
opt_result!(file_out.write_all(&encrypted), "Write file failed: {}");
progress.position(total_len);
}
}
let mut key = key;

View File

@@ -11,6 +11,7 @@ use crate::cmd_version::CmdVersion;
mod consts;
mod util;
mod util_process;
mod util_piv;
mod util_pgp;
mod util_ecdh;

28
src/util_process.rs Normal file
View File

@@ -0,0 +1,28 @@
use indicatif::{ProgressBar, ProgressStyle};
const PB_PROGRESS: &str = "#-";
const PB_TEMPLATE: &str = "{spinner:.green} [{elapsed_precise}] [{bar:40.cyan/blue}] {bytes}/{total_bytes} ({eta})";
pub struct Progress {
progress_bar: ProgressBar,
}
impl Progress {
pub fn new(total: u64) -> Self {
let progress_bar = ProgressBar::new(total);
progress_bar.set_style(ProgressStyle::default_bar()
.template(PB_TEMPLATE).expect("SHOULD NOT FAIL")
.progress_chars(PB_PROGRESS)
);
Self { progress_bar }
}
pub fn position(&self, position: u64) {
self.progress_bar.set_position(position)
}
pub fn finish(&self) {
self.progress_bar.finish_and_clear()
}
}