use std::collections::HashSet;
use ui::{backend::Backend, widgets::Text};
use super::{Expand, ExpandText};
use crate::{
question::{Choice, Options},
ExpandItem,
};
#[derive(Debug)]
pub struct ExpandBuilder<'a> {
opts: Options<'a>,
expand: Expand<'a>,
keys: HashSet<char>,
}
impl<'a> ExpandBuilder<'a> {
pub(crate) fn new(name: String) -> Self {
ExpandBuilder {
opts: Options::new(name),
expand: Default::default(),
keys: HashSet::default(),
}
}
crate::impl_options_builder! {
message
when
ask_if_answered
on_esc
}
pub fn default(mut self, default: char) -> Self {
self.expand.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.expand.choices.set_page_size(page_size);
self
}
pub fn should_loop(mut self, should_loop: bool) -> Self {
self.expand.choices.set_should_loop(should_loop);
self
}
pub fn choice<I: Into<String>>(mut self, mut key: char, text: I) -> Self {
key = key.to_ascii_lowercase();
if key == 'h' {
panic!("Reserved key 'h'");
}
if self.keys.contains(&key) {
panic!("Duplicate key '{}'", key);
}
self.keys.insert(key);
self.expand.choices.choices.push(Choice::Choice(ExpandText {
key,
text: Text::new(text.into()),
}));
self
}
pub fn separator<I: Into<String>>(mut self, text: I) -> Self {
self.expand
.choices
.choices
.push(Choice::Separator(text.into()));
self
}
pub fn default_separator(mut self) -> Self {
self.expand.choices.choices.push(Choice::DefaultSeparator);
self
}
pub fn choices<I, T>(mut self, choices: I) -> Self
where
T: Into<Choice<ExpandItem>>,
I: IntoIterator<Item = T>,
{
let Self {
ref mut keys,
ref mut expand,
..
} = self;
expand.choices.choices.extend(choices.into_iter().map(|c| {
c.into().map(|ExpandItem { text, mut key }| {
key = key.to_ascii_lowercase();
if key == 'h' {
panic!("Reserved key 'h'");
}
if keys.contains(&key) {
panic!("Duplicate key '{}'", key);
}
keys.insert(key);
ExpandText {
text: Text::new(text),
key,
}
})
}));
self
}
crate::impl_transform_builder! {
ExpandItem; expand
}
pub fn build(self) -> crate::question::Question<'a> {
if !self.expand.has_valid_default() {
panic!(
"Invalid default '{}' does not occur in the given choices",
self.expand.default
);
}
crate::question::Question::new(
self.opts,
crate::question::QuestionKind::Expand(self.expand),
)
}
}
impl<'a> From<ExpandBuilder<'a>> for crate::question::Question<'a> {
fn from(builder: ExpandBuilder<'a>) -> Self {
builder.build()
}
}