1use std::collections::HashSet;
2
3use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
6pub struct AskOption {
7 pub key: String,
8 pub label: String,
9}
10
11#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
12pub struct AskQuestion {
13 pub prompt: String,
14 pub options: Vec<AskOption>,
15 #[serde(rename = "multiSelect")]
16 pub multi_select: bool,
17}
18
19#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
20#[serde(tag = "kind", rename_all = "camelCase")]
21pub enum AskResult {
22 Answered {
23 answers: Vec<Vec<String>>,
24 by: String,
25 comment: Option<String>,
26 #[serde(default)]
27 timed_out: bool,
28 },
29 TimedOut {
30 selected: Option<String>,
31 by: Option<String>,
32 comment: Option<String>,
33 #[serde(default)]
34 timed_out: bool,
35 },
36 Invalidated {
37 reason: String,
38 selected: Option<String>,
39 by: Option<String>,
40 comment: Option<String>,
41 #[serde(default)]
42 timed_out: bool,
43 },
44}
45
46impl AskResult {
47 pub fn answered(answers: Vec<Vec<String>>, by: impl Into<String>) -> Self {
48 Self::Answered {
49 answers,
50 by: by.into(),
51 comment: None,
52 timed_out: false,
53 }
54 }
55}
56
57pub fn legacy_selected(result: &AskResult) -> Option<String> {
58 match result {
59 AskResult::Answered { answers, .. } if answers.len() == 1 && answers[0].len() == 1 => {
60 answers[0].first().cloned()
61 }
62 _ => None,
63 }
64}
65
66#[derive(Debug, Clone, Serialize, Deserialize)]
67pub struct AskRequest {
68 pub session_id: String,
69 pub chat_id: String,
70 pub lark_app_id: String,
71 pub root_message_id: Option<String>,
72 pub questions: Vec<AskQuestion>,
73 pub timeout_ms: u64,
74 pub approvers: HashSet<String>,
75}