use ui::{backend::Backend, widgets::Text};
use super::MultiSelect;
use crate::{
question::{Choice, Options},
ListItem,
};
#[derive(Debug)]
pub struct MultiSelectBuilder<'a> {
opts: Options<'a>,
multi_select: MultiSelect<'a>,
}
impl<'a> MultiSelectBuilder<'a> {
pub(crate) fn new(name: String) -> Self {
MultiSelectBuilder {
opts: Options::new(name),
multi_select: Default::default(),
}
}
crate::impl_options_builder! {
message
when
ask_if_answered
on_esc
}
pub fn page_size(mut self, page_size: usize) -> Self {
assert!(page_size >= 5, "page size can be a minimum of 5");
self.multi_select.choices.set_page_size(page_size);
self
}
pub fn should_loop(mut self, should_loop: bool) -> Self {
self.multi_select.choices.set_should_loop(should_loop);
self
}
pub fn choice<I: Into<String>>(self, text: I) -> Self {
self.choice_with_default(text.into(), false)
}
pub fn choice_with_default<I: Into<String>>(mut self, text: I, default: bool) -> Self {
self.multi_select
.choices
.choices
.push(Choice::Choice(Text::new(text.into())));
self.multi_select.selected.push(default);
self
}
pub fn separator<I: Into<String>>(mut self, text: I) -> Self {
self.multi_select
.choices
.choices
.push(Choice::Separator(text.into()));
self.multi_select.selected.push(false);
self
}
pub fn default_separator(mut self) -> Self {
self.multi_select
.choices
.choices
.push(Choice::DefaultSeparator);
self.multi_select.selected.push(false);
self
}
pub fn choices<I, T>(mut self, choices: I) -> Self
where
T: Into<Choice<String>>,
I: IntoIterator<Item = T>,
{
self.multi_select
.choices
.choices
.extend(choices.into_iter().map(|c| c.into().map(Text::new)));
self.multi_select
.selected
.resize(self.multi_select.choices.len(), false);
self
}
pub fn choices_with_default<I, T>(mut self, choices: I) -> Self
where
T: Into<Choice<(String, bool)>>,
I: IntoIterator<Item = T>,
{
let iter = choices.into_iter();
self.multi_select
.selected
.reserve(iter.size_hint().0.saturating_add(1));
self.multi_select
.choices
.choices
.reserve(iter.size_hint().0.saturating_add(1));
for choice in iter {
match choice.into() {
Choice::Choice((choice, selected)) => {
self.multi_select
.choices
.choices
.push(Choice::Choice(Text::new(choice)));
self.multi_select.selected.push(selected);
}
Choice::Separator(s) => {
self.multi_select.choices.choices.push(Choice::Separator(s));
self.multi_select.selected.push(false);
}
Choice::DefaultSeparator => {
self.multi_select
.choices
.choices
.push(Choice::DefaultSeparator);
self.multi_select.selected.push(false);
}
}
}
self
}
crate::impl_filter_builder! {
Vec<bool>; multi_select
}
crate::impl_validate_builder! {
[bool]; multi_select
}
crate::impl_transform_builder! {
[ListItem]; multi_select
}
pub fn build(self) -> crate::question::Question<'a> {
crate::question::Question::new(
self.opts,
crate::question::QuestionKind::MultiSelect(self.multi_select),
)
}
}
impl<'a> From<MultiSelectBuilder<'a>> for crate::question::Question<'a> {
fn from(builder: MultiSelectBuilder<'a>) -> Self {
builder.build()
}
}