use crate::{ElicitCommunicator, ElicitResult, Elicitation, Prompt};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub enum VecStyle {
#[default]
Default,
}
impl Prompt for VecStyle {
fn prompt() -> Option<&'static str> {
None
}
}
impl Elicitation for VecStyle {
type Style = VecStyle;
#[tracing::instrument(skip(_communicator), level = "trace")]
async fn elicit<C: ElicitCommunicator>(_communicator: &C) -> ElicitResult<Self> {
Ok(Self::Default)
}
}
impl<T: Elicitation + Send> Prompt for Vec<T> {
fn prompt() -> Option<&'static str> {
Some("Would you like to add items to this collection?")
}
}
impl<T: Elicitation + Send> Elicitation for Vec<T> {
type Style = VecStyle;
#[tracing::instrument(skip(communicator), fields(item_type = std::any::type_name::<T>()))]
async fn elicit<C: ElicitCommunicator>(communicator: &C) -> ElicitResult<Self> {
let mut items = Vec::new();
tracing::debug!("Eliciting vector");
loop {
let add_more = if items.is_empty() {
tracing::debug!("Prompting for first item");
bool::elicit(communicator).await?
} else {
tracing::debug!(count = items.len(), "Prompting for additional item");
bool::elicit(communicator).await?
};
if !add_more {
tracing::debug!(final_count = items.len(), "Collection complete");
break;
}
tracing::debug!("Eliciting item");
let item = T::elicit(communicator).await?;
items.push(item);
}
Ok(items)
}
}