use ui::{backend::Backend, widgets::Text};
use super::RawSelect;
use crate::{
question::{Choice, Options},
ListItem,
};
#[derive(Debug)]
pub struct RawSelectBuilder<'a> {
opts: Options<'a>,
raw_select: RawSelect<'a>,
choice_count: usize,
}
impl<'a> RawSelectBuilder<'a> {
pub(crate) fn new(name: String) -> Self {
RawSelectBuilder {
opts: Options::new(name),
raw_select: Default::default(),
choice_count: 1,
}
}
crate::impl_options_builder! {
message
when
ask_if_answered
on_esc
}
pub fn default(mut self, default: usize) -> Self {
self.raw_select.choices.set_default(default);
self
}
pub fn page_size(mut self, page_size: usize) -> Self {
assert!(page_size >= 5, "page size can be a minimum of 5");
self.raw_select.choices.set_page_size(page_size);
self
}
pub fn should_loop(mut self, should_loop: bool) -> Self {
self.raw_select.choices.set_should_loop(should_loop);
self
}
pub fn choice<I: Into<String>>(mut self, text: I) -> Self {
self.raw_select
.choices
.choices
.push(Choice::Choice((self.choice_count, Text::new(text.into()))));
self.choice_count += 1;
self
}
pub fn separator<I: Into<String>>(mut self, text: I) -> Self {
self.raw_select
.choices
.choices
.push(Choice::Separator(text.into()));
self
}
pub fn default_separator(mut self) -> Self {
self.raw_select
.choices
.choices
.push(Choice::DefaultSeparator);
self
}
pub fn choices<I, T>(mut self, choices: I) -> Self
where
T: Into<Choice<String>>,
I: IntoIterator<Item = T>,
{
let choice_count = &mut self.choice_count;
self.raw_select
.choices
.choices
.extend(choices.into_iter().map(|choice| {
choice.into().map(|c| {
let choice = (*choice_count, Text::new(c));
*choice_count += 1;
choice
})
}));
self
}
crate::impl_transform_builder! {
ListItem; raw_select
}
pub fn build(mut self) -> crate::question::Question<'a> {
let num_choices = self
.raw_select
.choices
.choices
.iter()
.rfind(|c| c.is_choice())
.and_then(|c| match c {
Choice::Choice((i, _)) => Some(*i),
_ => None,
})
.unwrap_or(0);
self.raw_select.max_index_width = (num_choices as f64).log10() as u16 + 1;
crate::question::Question::new(
self.opts,
crate::question::QuestionKind::RawSelect(self.raw_select),
)
}
}
impl<'a> From<RawSelectBuilder<'a>> for crate::question::Question<'a> {
fn from(builder: RawSelectBuilder<'a>) -> Self {
builder.build()
}
}