use ui::{backend::Backend, events::EventIterator};
use super::{Options, Question, QuestionKind};
use crate::{Answer, Answers};
pub trait Prompt: std::fmt::Debug {
fn ask(
self,
message: String,
answers: &Answers,
backend: &mut dyn Backend,
events: &mut dyn EventIterator,
) -> ui::Result<Option<Answer>>;
}
pub(super) trait CustomPromptInteral: std::fmt::Debug {
fn ask(
&mut self,
message: String,
answers: &Answers,
backend: &mut dyn Backend,
events: &mut dyn EventIterator,
) -> ui::Result<Option<Answer>>;
}
impl<T: Prompt> CustomPromptInteral for Option<T> {
fn ask(
&mut self,
message: String,
answers: &Answers,
backend: &mut dyn Backend,
events: &mut dyn EventIterator,
) -> ui::Result<Option<Answer>> {
self.take()
.expect("Prompt::ask called twice")
.ask(message, answers, backend, events)
}
}
#[derive(Debug)]
pub struct CustomPromptBuilder<'a> {
opts: Options<'a>,
prompt: Box<dyn CustomPromptInteral + 'a>,
}
impl<'a> CustomPromptBuilder<'a> {
pub(super) fn new(name: String, prompt: Box<dyn CustomPromptInteral + 'a>) -> Self {
Self {
opts: Options::new(name),
prompt,
}
}
crate::impl_options_builder! {
message
when
ask_if_answered
}
pub fn build(self) -> Question<'a> {
Question::new(self.opts, QuestionKind::Custom(self.prompt))
}
}
impl<'a> From<CustomPromptBuilder<'a>> for Question<'a> {
fn from(builder: CustomPromptBuilder<'a>) -> Self {
builder.build()
}
}