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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
use std::io;
use crate::theme::{SimpleTheme, TermThemeRenderer, Theme};
use console::Term;
pub struct Confirm<'a> {
prompt: String,
default: bool,
show_default: bool,
theme: &'a dyn Theme,
}
impl<'a> Default for Confirm<'a> {
fn default() -> Confirm<'a> {
Confirm::new()
}
}
impl<'a> Confirm<'a> {
pub fn new() -> Confirm<'static> {
Confirm::with_theme(&SimpleTheme)
}
pub fn with_theme(theme: &'a dyn Theme) -> Confirm<'a> {
Confirm {
prompt: "".into(),
default: true,
show_default: true,
theme,
}
}
pub fn with_prompt<S: Into<String>>(&mut self, prompt: S) -> &mut Confirm<'a> {
self.prompt = prompt.into();
self
}
#[deprecated(note = "Use with_prompt() instead", since = "0.6.0")]
#[inline]
pub fn with_text(&mut self, text: &str) -> &mut Confirm<'a> {
self.with_prompt(text)
}
pub fn default(&mut self, val: bool) -> &mut Confirm<'a> {
self.default = val;
self
}
pub fn show_default(&mut self, val: bool) -> &mut Confirm<'a> {
self.show_default = val;
self
}
pub fn interact(&self) -> io::Result<bool> {
self.interact_on(&Term::stderr())
}
pub fn interact_on(&self, term: &Term) -> io::Result<bool> {
let mut render = TermThemeRenderer::new(term, self.theme);
render.confirm_prompt(
&self.prompt,
if self.show_default {
Some(self.default)
} else {
None
},
)?;
term.hide_cursor()?;
term.flush()?;
loop {
let input = term.read_char()?;
let rv = match input {
'y' | 'Y' => true,
'n' | 'N' => false,
'\n' | '\r' => self.default,
_ => {
continue;
}
};
term.clear_line()?;
render.confirm_prompt_selection(&self.prompt, rv)?;
term.show_cursor()?;
term.flush()?;
return Ok(rv);
}
}
}