use ui::{backend::Backend, events::EventIterator};
use crate::{Answer, Answers, Question};
#[derive(Debug, Clone, PartialEq)]
pub struct PromptModule<Q> {
questions: Q,
answers: Answers,
}
impl<'a, Q> PromptModule<Q>
where
Q: Iterator<Item = Question<'a>>,
{
pub fn new<I>(questions: I) -> Self
where
I: IntoIterator<IntoIter = Q, Item = Question<'a>>,
{
Self {
answers: Answers::default(),
questions: questions.into_iter(),
}
}
pub fn with_answers(mut self, answers: Answers) -> Self {
self.answers = answers;
self
}
#[cfg(any(feature = "crossterm", feature = "termion"))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "crossterm", feature = "termion"))))]
pub fn prompt(&mut self) -> crate::Result<Option<&mut Answer>> {
let stdout = std::io::stdout();
let mut stdout = ui::backend::get_backend(stdout.lock());
self.prompt_with(&mut stdout, &mut ui::events::get_events())
}
pub fn prompt_with<B, E>(
&mut self,
backend: &mut B,
events: &mut E,
) -> crate::Result<Option<&mut Answer>>
where
B: Backend,
E: EventIterator,
{
for question in self.questions.by_ref() {
if let Some((name, answer)) = question.ask(&self.answers, backend, events)? {
return Ok(Some(self.answers.insert(name, answer)));
}
}
Ok(None)
}
#[cfg(any(feature = "crossterm", feature = "termion"))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "crossterm", feature = "termion"))))]
pub fn prompt_all(self) -> crate::Result<Answers> {
let stdout = std::io::stdout();
let mut stdout = ui::backend::get_backend(stdout.lock());
let mut events = ui::events::get_events();
self.prompt_all_with(&mut stdout, &mut events)
}
pub fn prompt_all_with<B, E>(
mut self,
backend: &mut B,
events: &mut E,
) -> crate::Result<Answers>
where
B: Backend,
E: EventIterator,
{
self.answers.reserve(self.questions.size_hint().0);
while self.prompt_with(backend, events)?.is_some() {}
Ok(self.answers)
}
pub fn into_answers(self) -> Answers {
self.answers
}
}
#[cfg(feature = "macros")]
#[cfg_attr(docsrs, doc(cfg(feature = "macros")))]
#[macro_export]
macro_rules! prompt_module {
($($tt:tt)*) => {
$crate::PromptModule::new($crate::questions! [ $($tt)* ])
};
}