#![allow(non_snake_case)]
use crate::{ElicitCommunicator, ElicitResult, Elicitation, Prompt};
macro_rules! impl_tuple_elicit {
($($T:ident $idx:tt),+) => {
paste::paste! {
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub enum [<Tuple $( $idx )+ Style>] {
#[default]
Default,
}
impl Prompt for [<Tuple $( $idx )+ Style>] {
fn prompt() -> Option<&'static str> {
None
}
}
impl Elicitation for [<Tuple $( $idx )+ Style>] {
type Style = [<Tuple $( $idx )+ Style>];
#[tracing::instrument(skip(_communicator), level = "trace")]
async fn elicit<C: ElicitCommunicator>(_communicator: &C) -> ElicitResult<Self> {
Ok(Self::Default)
}
}
}
impl<$($T),+> Prompt for ($($T,)+)
where
$($T: Elicitation + Send,)+
{
fn prompt() -> Option<&'static str> {
Some("Eliciting tuple elements:")
}
}
impl<$($T),+> Elicitation for ($($T,)+)
where
$($T: Elicitation + Send,)+
{
paste::paste! {
type Style = [<Tuple $( $idx )+ Style>];
}
#[tracing::instrument(skip(communicator), fields(
tuple_size = count!($($T)+),
types = concat!($(stringify!($T), ", "),+)
))]
async fn elicit<C: ElicitCommunicator>(
communicator: &C,
) -> ElicitResult<Self> {
tracing::debug!("Eliciting tuple");
$(
tracing::debug!(index = $idx, type_name = std::any::type_name::<$T>(), "Eliciting tuple element");
let $T = $T::elicit(communicator).await?;
)+
tracing::debug!("Tuple complete");
Ok(($($T,)+))
}
}
};
}
macro_rules! count {
() => (0);
($head:tt $($tail:tt)*) => (1 + count!($($tail)*));
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub enum UnitStyle {
#[default]
Default,
}
impl Prompt for UnitStyle {
fn prompt() -> Option<&'static str> {
None
}
}
impl Elicitation for UnitStyle {
type Style = UnitStyle;
#[tracing::instrument(skip(_communicator), level = "trace")]
async fn elicit<C: ElicitCommunicator>(_communicator: &C) -> ElicitResult<Self> {
Ok(Self::Default)
}
}
impl Prompt for () {
fn prompt() -> Option<&'static str> {
None
}
}
impl Elicitation for () {
type Style = UnitStyle;
#[tracing::instrument(skip(_communicator), level = "trace")]
async fn elicit<C: ElicitCommunicator>(_communicator: &C) -> ElicitResult<Self> {
tracing::debug!("Eliciting unit type ()");
Ok(())
}
}
impl_tuple_elicit!(T0 0);
impl_tuple_elicit!(T0 0, T1 1);
impl_tuple_elicit!(T0 0, T1 1, T2 2);
impl_tuple_elicit!(T0 0, T1 1, T2 2, T3 3);
impl_tuple_elicit!(T0 0, T1 1, T2 2, T3 3, T4 4);
impl_tuple_elicit!(T0 0, T1 1, T2 2, T3 3, T4 4, T5 5);
impl_tuple_elicit!(T0 0, T1 1, T2 2, T3 3, T4 4, T5 5, T6 6);
impl_tuple_elicit!(T0 0, T1 1, T2 2, T3 3, T4 4, T5 5, T6 6, T7 7);
impl_tuple_elicit!(T0 0, T1 1, T2 2, T3 3, T4 4, T5 5, T6 6, T7 7, T8 8);
impl_tuple_elicit!(T0 0, T1 1, T2 2, T3 3, T4 4, T5 5, T6 6, T7 7, T8 8, T9 9);
impl_tuple_elicit!(T0 0, T1 1, T2 2, T3 3, T4 4, T5 5, T6 6, T7 7, T8 8, T9 9, T10 10);
impl_tuple_elicit!(T0 0, T1 1, T2 2, T3 3, T4 4, T5 5, T6 6, T7 7, T8 8, T9 9, T10 10, T11 11);