Skip to main content

elicitation/collections/
btreeset.rs

1//! BTreeSet<T> implementation for ordered unique item collection.
2
3use crate::{ElicitClient, ElicitResult, Elicitation, Prompt};
4use std::collections::BTreeSet;
5
6// Default-only style for BTreeSet
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
8pub enum BTreeSetStyle {
9    #[default]
10    Default,
11}
12
13impl Prompt for BTreeSetStyle {
14    fn prompt() -> Option<&'static str> {
15        None
16    }
17}
18
19impl Elicitation for BTreeSetStyle {
20    type Style = BTreeSetStyle;
21
22    #[tracing::instrument(skip(_client), level = "trace")]
23    async fn elicit(_client: &ElicitClient<'_>) -> ElicitResult<Self> {
24        Ok(Self::Default)
25    }
26}
27
28impl<T> Prompt for BTreeSet<T>
29where
30    T: Elicitation + Ord + Send,
31{
32    fn prompt() -> Option<&'static str> {
33        Some("Would you like to add items to this ordered set?")
34    }
35}
36
37impl<T> Elicitation for BTreeSet<T>
38where
39    T: Elicitation + Ord + Send,
40{
41    type Style = BTreeSetStyle;
42
43    #[tracing::instrument(skip(client), fields(item_type = std::any::type_name::<T>()))]
44    async fn elicit(client: &ElicitClient<'_>) -> ElicitResult<Self> {
45        let mut set = BTreeSet::new();
46        tracing::debug!("Eliciting BTreeSet");
47
48        loop {
49            let add_more = if set.is_empty() {
50                tracing::debug!("Prompting for first item");
51                bool::elicit(client).await?
52            } else {
53                tracing::debug!(count = set.len(), "Prompting for additional item");
54                bool::elicit(client).await?
55            };
56
57            if !add_more {
58                tracing::debug!(final_count = set.len(), "Set complete");
59                break;
60            }
61
62            tracing::debug!("Eliciting item");
63            let item = T::elicit(client).await?;
64
65            // Automatic duplicate handling - sets ignore duplicates
66            if !set.insert(item) {
67                tracing::debug!("Duplicate item ignored (already in set)");
68            }
69        }
70
71        Ok(set)
72    }
73}