1use serde::{Deserialize, Serialize};
8use std::collections::HashMap;
9use uuid::Uuid;
10
11#[derive(Debug, Clone, Serialize, Deserialize)]
13pub struct ElicitationRequest {
14 pub request_id: Uuid,
16 pub server_name: String,
18 pub schema: ElicitationSchema,
20 pub message: String,
22 pub required: bool,
24}
25
26impl ElicitationRequest {
27 #[must_use]
29 pub fn new(server_name: impl Into<String>, message: impl Into<String>) -> Self {
30 Self {
31 request_id: Uuid::new_v4(),
32 server_name: server_name.into(),
33 schema: ElicitationSchema::Text {
34 placeholder: None,
35 max_length: None,
36 },
37 message: message.into(),
38 required: true,
39 }
40 }
41
42 #[must_use]
44 pub fn with_schema(mut self, schema: ElicitationSchema) -> Self {
45 self.schema = schema;
46 self
47 }
48
49 #[must_use]
51 pub fn optional(mut self) -> Self {
52 self.required = false;
53 self
54 }
55}
56
57#[derive(Debug, Clone, Serialize, Deserialize)]
59#[serde(rename_all = "snake_case")]
60pub enum ElicitationSchema {
61 Text {
63 placeholder: Option<String>,
65 max_length: Option<usize>,
67 },
68 Secret {
70 placeholder: Option<String>,
72 },
73 Select {
75 options: Vec<SelectOption>,
77 multiple: bool,
79 },
80 Confirm {
82 default: bool,
84 },
85}
86
87#[derive(Debug, Clone, Serialize, Deserialize)]
89pub struct SelectOption {
90 pub value: String,
92 pub label: String,
94 pub description: Option<String>,
96}
97
98impl SelectOption {
99 #[must_use]
101 pub fn new(value: impl Into<String>, label: impl Into<String>) -> Self {
102 Self {
103 value: value.into(),
104 label: label.into(),
105 description: None,
106 }
107 }
108
109 #[must_use]
111 pub fn with_description(mut self, description: impl Into<String>) -> Self {
112 self.description = Some(description.into());
113 self
114 }
115}
116
117#[derive(Debug, Clone, Serialize, Deserialize)]
119pub struct ElicitationResponse {
120 pub request_id: Uuid,
122 pub action: ElicitationAction,
124}
125
126impl ElicitationResponse {
127 #[must_use]
129 pub fn submit(request_id: Uuid, value: serde_json::Value) -> Self {
130 Self {
131 request_id,
132 action: ElicitationAction::Submit { value },
133 }
134 }
135
136 #[must_use]
138 pub fn cancel(request_id: Uuid) -> Self {
139 Self {
140 request_id,
141 action: ElicitationAction::Cancel,
142 }
143 }
144
145 #[must_use]
147 pub fn dismiss(request_id: Uuid) -> Self {
148 Self {
149 request_id,
150 action: ElicitationAction::Dismiss,
151 }
152 }
153}
154
155#[derive(Debug, Clone, Serialize, Deserialize)]
157#[serde(rename_all = "snake_case")]
158pub enum ElicitationAction {
159 Submit {
161 value: serde_json::Value,
163 },
164 Cancel,
166 Dismiss,
168}
169
170#[derive(Debug, Clone, Serialize, Deserialize)]
172pub struct UrlElicitationRequest {
173 pub request_id: Uuid,
175 pub server_name: String,
177 pub url: String,
179 pub message: String,
181 pub elicitation_type: UrlElicitationType,
183}
184
185impl UrlElicitationRequest {
186 #[must_use]
188 pub fn new(
189 server_name: impl Into<String>,
190 url: impl Into<String>,
191 message: impl Into<String>,
192 ) -> Self {
193 Self {
194 request_id: Uuid::new_v4(),
195 server_name: server_name.into(),
196 url: url.into(),
197 message: message.into(),
198 elicitation_type: UrlElicitationType::OAuth,
199 }
200 }
201
202 #[must_use]
204 pub fn with_type(mut self, elicitation_type: UrlElicitationType) -> Self {
205 self.elicitation_type = elicitation_type;
206 self
207 }
208}
209
210#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
212#[serde(rename_all = "snake_case")]
213pub enum UrlElicitationType {
214 OAuth,
216 Payment,
218 Credentials,
220 External,
222}
223
224#[derive(Debug, Clone, Serialize, Deserialize)]
226pub struct UrlElicitationResponse {
227 pub request_id: Uuid,
229 pub completed: bool,
231 pub callback_data: Option<HashMap<String, String>>,
233 pub error: Option<String>,
235}
236
237impl UrlElicitationResponse {
238 #[must_use]
240 pub fn completed(request_id: Uuid) -> Self {
241 Self {
242 request_id,
243 completed: true,
244 callback_data: None,
245 error: None,
246 }
247 }
248
249 #[must_use]
251 pub fn not_completed(request_id: Uuid) -> Self {
252 Self {
253 request_id,
254 completed: false,
255 callback_data: None,
256 error: None,
257 }
258 }
259
260 #[must_use]
262 pub fn with_callback_data(mut self, data: HashMap<String, String>) -> Self {
263 self.callback_data = Some(data);
264 self
265 }
266}