zagens_core/
user_input.rs1use serde::{Deserialize, Serialize};
4use serde_json::Value;
5use zagens_tools::ToolError;
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct UserInputOption {
9 pub label: String,
10 pub description: String,
11}
12
13#[derive(Debug, Clone, Serialize, Deserialize)]
14pub struct UserInputQuestion {
15 pub header: String,
16 pub id: String,
17 pub question: String,
18 pub options: Vec<UserInputOption>,
19}
20
21#[derive(Debug, Clone, Serialize, Deserialize)]
22pub struct UserInputRequest {
23 pub questions: Vec<UserInputQuestion>,
24}
25
26impl UserInputRequest {
27 pub fn from_value(value: &Value) -> Result<Self, ToolError> {
28 let request: UserInputRequest = serde_json::from_value(value.clone()).map_err(|e| {
29 ToolError::invalid_input(format!("Invalid request_user_input payload: {e}"))
30 })?;
31 request.validate()?;
32 Ok(request)
33 }
34
35 pub fn validate(&self) -> Result<(), ToolError> {
36 if self.questions.is_empty() {
37 return Err(ToolError::invalid_input(
38 "request_user_input.questions must be non-empty",
39 ));
40 }
41 if self.questions.len() > 3 {
42 return Err(ToolError::invalid_input(
43 "request_user_input.questions must contain 1 to 3 items",
44 ));
45 }
46 for q in &self.questions {
47 if q.header.trim().is_empty() {
48 return Err(ToolError::invalid_input(
49 "request_user_input.questions.header cannot be empty",
50 ));
51 }
52 if q.id.trim().is_empty() {
53 return Err(ToolError::invalid_input(
54 "request_user_input.questions.id cannot be empty",
55 ));
56 }
57 if q.question.trim().is_empty() {
58 return Err(ToolError::invalid_input(
59 "request_user_input.questions.question cannot be empty",
60 ));
61 }
62 if q.options.len() < 2 || q.options.len() > 3 {
63 return Err(ToolError::invalid_input(
64 "request_user_input.questions.options must contain 2 or 3 items",
65 ));
66 }
67 for opt in &q.options {
68 if opt.label.trim().is_empty() {
69 return Err(ToolError::invalid_input(
70 "request_user_input option label cannot be empty",
71 ));
72 }
73 if opt.description.trim().is_empty() {
74 return Err(ToolError::invalid_input(
75 "request_user_input option description cannot be empty",
76 ));
77 }
78 }
79 }
80 Ok(())
81 }
82}