feat: v0.4.0, add progress bar
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
28
src/util_process.rs
Normal 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()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user