Add select prompt
parent
215c235f4b
commit
9cf4d225d7
@ -0,0 +1,69 @@
|
||||
use dialoguer::{theme::Theme, FuzzySelect, Select};
|
||||
|
||||
use super::{create_labeled_error, UserPrompt};
|
||||
|
||||
pub enum GenericSelect<'a> {
|
||||
Fuzzy(FuzzySelect<'a>),
|
||||
Normal(Select<'a>),
|
||||
}
|
||||
|
||||
impl<'a> GenericSelect<'a> {
|
||||
pub fn fuzzy(theme: &'a dyn Theme) -> Self {
|
||||
Self::Fuzzy(FuzzySelect::with_theme(theme))
|
||||
}
|
||||
|
||||
pub fn normal(theme: &'a dyn Theme) -> Self {
|
||||
Self::Normal(Select::with_theme(theme))
|
||||
}
|
||||
|
||||
pub fn items<T: ToString>(&mut self, items: &[T]) -> &mut Self {
|
||||
match self {
|
||||
GenericSelect::Fuzzy(f) => f.items(items).nop(),
|
||||
GenericSelect::Normal(n) => n.items(items).nop(),
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
pub fn default(&mut self, val: usize) -> &mut Self {
|
||||
match self {
|
||||
GenericSelect::Fuzzy(f) => f.default(val).nop(),
|
||||
GenericSelect::Normal(n) => n.default(val).nop(),
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_prompt<S: Into<String>>(&mut self, prompt: S) -> &mut Self {
|
||||
match self {
|
||||
GenericSelect::Fuzzy(f) => f.with_prompt(prompt).nop(),
|
||||
GenericSelect::Normal(n) => n.with_prompt(prompt).nop(),
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> UserPrompt for GenericSelect<'a> {
|
||||
type Output = usize;
|
||||
|
||||
fn prompt(&self) -> Result<Self::Output, nu_plugin::LabeledError> {
|
||||
match self {
|
||||
GenericSelect::Fuzzy(f) => f.interact(),
|
||||
GenericSelect::Normal(n) => n.interact(),
|
||||
}
|
||||
.map_err(create_labeled_error)
|
||||
}
|
||||
|
||||
fn prompt_opt(&self) -> Result<Option<Self::Output>, nu_plugin::LabeledError> {
|
||||
match self {
|
||||
GenericSelect::Fuzzy(f) => f.interact_opt(),
|
||||
GenericSelect::Normal(n) => n.interact_opt(),
|
||||
}
|
||||
.map_err(create_labeled_error)
|
||||
}
|
||||
}
|
||||
|
||||
trait Nop {
|
||||
fn nop(&mut self) {}
|
||||
}
|
||||
|
||||
impl<'a> Nop for Select<'a> {}
|
||||
impl<'a> Nop for FuzzySelect<'a> {}
|
@ -0,0 +1,33 @@
|
||||
use std::io;
|
||||
|
||||
use nu_plugin::LabeledError;
|
||||
mod generic_select;
|
||||
pub use generic_select::GenericSelect;
|
||||
|
||||
pub trait UserPrompt {
|
||||
type Output;
|
||||
|
||||
fn prompt(&self) -> Result<Self::Output, LabeledError>;
|
||||
|
||||
fn prompt_opt(&self) -> Result<Option<Self::Output>, LabeledError>;
|
||||
}
|
||||
|
||||
impl<'a> UserPrompt for dialoguer::Confirm<'a> {
|
||||
type Output = bool;
|
||||
|
||||
fn prompt(&self) -> Result<Self::Output, LabeledError> {
|
||||
self.interact().map_err(create_labeled_error)
|
||||
}
|
||||
|
||||
fn prompt_opt(&self) -> Result<Option<Self::Output>, LabeledError> {
|
||||
self.interact_opt().map_err(create_labeled_error)
|
||||
}
|
||||
}
|
||||
|
||||
fn create_labeled_error(e: io::Error) -> LabeledError {
|
||||
LabeledError {
|
||||
label: "Failed to prompt user".into(),
|
||||
msg: e.to_string(),
|
||||
span: None,
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
use nu_plugin::{EvaluatedCall, LabeledError};
|
||||
use nu_protocol::Value;
|
||||
|
||||
use crate::{
|
||||
prompt::{GenericSelect, UserPrompt},
|
||||
DialogPlugin,
|
||||
};
|
||||
|
||||
impl DialogPlugin {
|
||||
pub(crate) fn select(
|
||||
&self,
|
||||
call: &EvaluatedCall,
|
||||
_input: &Value,
|
||||
) -> Result<Value, LabeledError> {
|
||||
let mut options: Vec<String> = call.req(0)?;
|
||||
|
||||
let mut select = if call.has_flag("fuzzy") {
|
||||
GenericSelect::fuzzy(&*self.theme)
|
||||
} else {
|
||||
GenericSelect::normal(&*self.theme)
|
||||
};
|
||||
select.items(&options);
|
||||
|
||||
if let Some(prompt) = call.get_flag::<String>("prompt")? {
|
||||
select.with_prompt(prompt);
|
||||
}
|
||||
if let Some(def) = call.get_flag::<usize>("default")? {
|
||||
select.default(def);
|
||||
}
|
||||
|
||||
let selection = select.prompt()?;
|
||||
let selected_item = options.remove(selection);
|
||||
|
||||
Ok(Value::String {
|
||||
val: selected_item,
|
||||
span: call.head,
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue