Skip to main content

elicitation/
paradigm.rs

1//! Interaction paradigm traits for elicitation patterns.
2
3use crate::Prompt;
4
5/// Select one value from a finite set (dropdown/radio button pattern).
6///
7/// This trait represents the conversational equivalent of a dropdown menu or
8/// radio button group. It is the natural elicitation mode for enums and
9/// categorical fields.
10///
11/// # Example
12///
13/// ```rust,no_run
14/// use elicitation::{Select, Prompt};
15///
16/// #[derive(Debug, Clone, Copy)]
17/// enum Color {
18///     Red,
19///     Green,
20///     Blue,
21/// }
22///
23/// impl Prompt for Color {
24///     fn prompt() -> Option<&'static str> {
25///         Some("Choose a color:")
26///     }
27/// }
28///
29/// impl Select for Color {
30///     fn options() -> &'static [Self] {
31///         &[Color::Red, Color::Green, Color::Blue]
32///     }
33///
34///     fn labels() -> &'static [&'static str] {
35///         &["Red", "Green", "Blue"]
36///     }
37///
38///     fn from_label(label: &str) -> Option<Self> {
39///         match label {
40///             "Red" => Some(Color::Red),
41///             "Green" => Some(Color::Green),
42///             "Blue" => Some(Color::Blue),
43///             _ => None,
44///         }
45///     }
46/// }
47/// ```
48pub trait Select: Prompt + Sized {
49    /// All valid options for this selection.
50    ///
51    /// Returns a static slice of all possible values. The MCP tool will
52    /// ensure the user selects one of these options.
53    fn options() -> &'static [Self];
54
55    /// Human-readable labels for each option.
56    ///
57    /// Returns labels corresponding to each value in `options()`. These
58    /// are presented to the user and used to parse their selection.
59    fn labels() -> &'static [&'static str];
60
61    /// Parse a label back into the type.
62    ///
63    /// Given a label string (from user selection), returns the corresponding
64    /// value, or `None` if the label is invalid.
65    ///
66    /// # Arguments
67    ///
68    /// * `label` - The label to parse
69    ///
70    /// # Returns
71    ///
72    /// `Some(Self)` if the label is valid, `None` otherwise.
73    fn from_label(label: &str) -> Option<Self>;
74}
75
76/// Binary confirmation (yes/no, true/false pattern).
77///
78/// This trait represents a yes/no confirmation dialog. It is the natural
79/// elicitation mode for boolean fields and confirmation prompts.
80///
81/// # Example
82///
83/// ```rust
84/// use elicitation::Affirm;
85///
86/// // bool implements Affirm by default
87/// fn requires_affirm<T: Affirm>() {}
88/// requires_affirm::<bool>();
89/// ```
90pub trait Affirm: Prompt {}
91
92/// Multi-field structured elicitation (form/wizard pattern).
93///
94/// This trait represents a multi-step form or wizard. It is the natural
95/// elicitation mode for structs and configuration objects.
96///
97/// The derive macro generates implementations of this trait for structs,
98/// creating a state machine that elicits each field in sequence.
99pub trait Survey: Prompt {
100    /// Field metadata for survey construction.
101    ///
102    /// Returns information about each field in the struct, used to drive
103    /// the elicitation state machine.
104    fn fields() -> &'static [FieldInfo];
105}
106
107/// Metadata for a single survey field.
108#[derive(Debug, Clone, PartialEq, Eq, Hash)]
109pub struct FieldInfo {
110    /// Field name in the struct.
111    pub name: &'static str,
112    /// Optional custom prompt for this field.
113    pub prompt: Option<&'static str>,
114    /// Type name for dispatching elicitation.
115    pub type_name: &'static str,
116}
117
118/// Permission-granting interaction with policy choices.
119///
120/// This trait represents a permission dialog with multiple policy options.
121/// It is used for authorization decisions and policy selection.
122///
123/// **Note**: Implementation of this paradigm is planned for v0.2.0.
124pub trait Authorize: Prompt + Sized {
125    /// Available permission policies.
126    ///
127    /// Returns a static slice of all available policy options.
128    fn policies() -> &'static [Self];
129}