-
Notifications
You must be signed in to change notification settings - Fork 142
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add 'interact_text_opt' and 'interact_text_on_opt' for 'Input' prompts #278
base: master
Are you sure you want to change the base?
Changes from 2 commits
4f6e627
05f6a3b
08630fc
3154935
b8f842a
1ca3639
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,5 @@ | ||
use std::{ | ||
cmp::Ordering, | ||
fmt::Debug, | ||
io, iter, | ||
str::FromStr, | ||
sync::{Arc, Mutex}, | ||
|
@@ -281,20 +280,46 @@ where | |
impl<T> Input<'_, T> | ||
where | ||
T: Clone + ToString + FromStr, | ||
<T as FromStr>::Err: Debug + ToString, | ||
<T as FromStr>::Err: ToString, | ||
{ | ||
/// Enables the user to enter a printable ascii sequence and returns the result. | ||
/// | ||
/// Its difference from [`interact`](Self::interact) is that it only allows ascii characters for string, | ||
/// while [`interact`](Self::interact) allows virtually any character to be used e.g arrow keys. | ||
/// | ||
/// The dialog is rendered on stderr. | ||
/// This unlike [`interact_text_opt`](Self::interact_text_opt) does not allow to quit with 'Esc' | ||
pub fn interact_text(self) -> Result<T> { | ||
self.interact_text_on(&Term::stderr()) | ||
} | ||
|
||
/// Enables the user to enter a printable ascii sequence and returns the result. | ||
/// | ||
/// Its difference from [`interact_opt`](Self::interact_opt) is that it only allows ascii characters for string, | ||
tbergerd marked this conversation as resolved.
Show resolved
Hide resolved
|
||
/// while [`interact_opt`](Self::interact_opt) allows virtually any character to be used e.g arrow keys. | ||
/// | ||
/// The dialog is rendered on stderr. | ||
/// Result contains `Some(T)` if user hit 'Enter' or `None` if user cancelled with 'Esc' | ||
#[inline] | ||
pub fn interact_text_opt(self) -> Result<Option<T>> { | ||
self.interact_text_on_opt(&Term::stderr()) | ||
} | ||
|
||
/// Like [`interact_text`](Self::interact_text) but allows a specific terminal to be set. | ||
pub fn interact_text_on(mut self, term: &Term) -> Result<T> { | ||
#[inline] | ||
pub fn interact_text_on(self, term: &Term) -> Result<T> { | ||
Ok(self | ||
._interact_text_on(term, false)? | ||
.ok_or_else(|| io::Error::new(io::ErrorKind::Other, "Quit not allowed in this case"))?) | ||
} | ||
|
||
/// Like [`interact_text_opt`](Self::interact_text_opt) but allows a specific terminal to be set. | ||
#[inline] | ||
pub fn interact_text_on_opt(self, term: &Term) -> Result<Option<T>> { | ||
self._interact_text_on(term, true) | ||
} | ||
|
||
fn _interact_text_on(mut self, term: &Term, allow_quit: bool) -> Result<Option<T>> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should follow a builder pattern here, so the signature of this function shouldn't change. |
||
if !term.is_term() { | ||
return Err(io::Error::new(io::ErrorKind::NotConnected, "not a terminal").into()); | ||
} | ||
|
@@ -313,11 +338,6 @@ where | |
}, | ||
)?; | ||
|
||
// Read input by keystroke so that we can suppress ascii control characters | ||
if !term.features().is_attended() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. note : removed this because the check is already performed at the beginning of the function (and returns an error instead which makes more sense) |
||
return Ok("".to_owned().parse::<T>().unwrap()); | ||
} | ||
|
||
let mut chars: Vec<char> = Vec::new(); | ||
let mut position = 0; | ||
#[cfg(feature = "history")] | ||
|
@@ -332,6 +352,12 @@ where | |
|
||
loop { | ||
match term.read_key()? { | ||
Key::Escape if allow_quit => { | ||
render.clear()?; | ||
term.flush()?; | ||
term.show_cursor()?; | ||
return Ok(None); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's instead add a new variant for the |
||
} | ||
Key::Backspace if position > 0 => { | ||
position -= 1; | ||
chars.remove(position); | ||
|
@@ -591,7 +617,7 @@ where | |
render.input_prompt_selection(&self.prompt, &default.to_string())?; | ||
} | ||
term.flush()?; | ||
return Ok(default.clone()); | ||
return Ok(Some(default.clone())); | ||
} else if !self.permit_empty { | ||
continue; | ||
} | ||
|
@@ -620,7 +646,7 @@ where | |
} | ||
term.flush()?; | ||
|
||
return Ok(value); | ||
return Ok(Some(value)); | ||
} | ||
Err(err) => { | ||
render.error(&err.to_string())?; | ||
|
@@ -629,13 +655,7 @@ where | |
} | ||
} | ||
} | ||
} | ||
|
||
impl<T> Input<'_, T> | ||
where | ||
T: Clone + ToString + FromStr, | ||
<T as FromStr>::Err: ToString, | ||
{ | ||
/// Enables user interaction and returns the result. | ||
/// | ||
/// Allows any characters as input, including e.g arrow keys. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are you removing this bound?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the bound was only required by the call to unwrap (in the dead code I removed in the same commit : 05f6a3b)
I figured I might as well remove it since it seems unnecessary (interact and interact_on didn't have this constraint).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then it's definitely worth fixing. I suggest making a separate PR for this and removal of the redundant check.