1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
use std::fmt::Write;
use std::path::PathBuf;
use std::sync::Arc;
use std::thread;
use fs_extra;
use indicatif::{InMemoryTerm, ProgressBar, ProgressDrawTarget, ProgressState, ProgressStyle};
use tuikit::prelude::{Attr, Color, Effect, Event, Term};
use crate::fm_error::FmResult;
fn setup(
action: String,
height: usize,
width: usize,
) -> FmResult<(InMemoryTerm, ProgressBar, fs_extra::dir::CopyOptions)> {
let in_mem = InMemoryTerm::new(height as u16, width as u16);
let pb = ProgressBar::with_draw_target(
Some(100),
ProgressDrawTarget::term_like(Box::new(in_mem.clone())),
);
pb.set_style(
ProgressStyle::with_template(
"{spinner} {action} [{elapsed}] [{wide_bar}] {percent}% ({eta})",
)
.unwrap()
.with_key("eta", |state: &ProgressState, w: &mut dyn Write| {
write!(w, "{:.1}s", state.eta().as_secs_f64()).unwrap()
})
.with_key("action", move |_: &ProgressState, w: &mut dyn Write| {
write!(w, "{}", &action).unwrap()
})
.progress_chars("#>-"),
);
let options = fs_extra::dir::CopyOptions::new();
Ok((in_mem, pb, options))
}
fn handle_progress_display(
in_mem: &InMemoryTerm,
pb: &ProgressBar,
term: &Arc<Term>,
process_info: fs_extra::TransitProcess,
) -> fs_extra::dir::TransitProcessResult {
pb.set_position(100 * process_info.copied_bytes / process_info.total_bytes);
let _ = term.print_with_attr(
1,
0,
&in_mem.to_owned().contents(),
Attr {
fg: Color::CYAN,
bg: Color::default(),
effect: Effect::REVERSE | Effect::BOLD,
},
);
let _ = term.present();
fs_extra::dir::TransitProcessResult::ContinueOrAbort
}
pub fn copy(sources: Vec<PathBuf>, dest: String, term: Arc<Term>) -> FmResult<()> {
let c_term = term.clone();
let (height, width) = term.term_size()?;
let (in_mem, pb, options) = setup("copy".to_owned(), height, width)?;
let handle_progress = move |process_info: fs_extra::TransitProcess| {
handle_progress_display(&in_mem, &pb, &term, process_info)
};
let _ = thread::spawn(move || {
fs_extra::copy_items_with_progress(&sources, &dest, &options, handle_progress)
.unwrap_or_default();
let _ = c_term.send_event(Event::User(()));
});
Ok(())
}
pub fn mover(sources: Vec<PathBuf>, dest: String, term: Arc<Term>) -> FmResult<()> {
let c_term = term.clone();
let (height, width) = term.term_size()?;
let (in_mem, pb, options) = setup("move".to_owned(), height, width)?;
let handle_progress = move |process_info: fs_extra::TransitProcess| {
handle_progress_display(&in_mem, &pb, &term, process_info)
};
let _ = thread::spawn(move || {
fs_extra::move_items_with_progress(&sources, dest, &options, handle_progress)
.unwrap_or_default();
let _ = c_term.send_event(Event::User(()));
});
Ok(())
}
|