1use crate::expr::Expr;
2use schemars::JsonSchema;
3use serde::{Deserialize, Serialize};
4use std::collections::BTreeMap;
5
6pub type StepId = String;
8
9#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
11#[serde(rename_all = "snake_case")]
12pub enum CardMode {
13 Text,
14 Json,
15 Card,
16}
17
18#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
20pub struct MessageStep {
21 pub mode: CardMode,
22 pub template: String,
23 #[serde(skip_serializing_if = "Option::is_none")]
24 pub next: Option<StepId>,
25}
26
27#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
29pub struct QuestionStep {
30 pub question_id: String,
31 #[serde(skip_serializing_if = "Option::is_none")]
32 pub next: Option<StepId>,
33}
34
35#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
37pub struct DecisionCase {
38 #[serde(rename = "if")]
39 pub if_expr: Expr,
40 pub goto: StepId,
41}
42
43#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
45pub struct DecisionStep {
46 pub cases: Vec<DecisionCase>,
47 #[serde(skip_serializing_if = "Option::is_none")]
48 pub default_goto: Option<StepId>,
49}
50
51#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
53pub struct FlowPolicy {
54 #[serde(default)]
55 pub allow_back: bool,
56 #[serde(default)]
57 pub allow_submit_all: bool,
58}
59
60#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
62#[serde(tag = "type", rename_all = "snake_case")]
63pub enum StepSpec {
64 Message(MessageStep),
65 Question(QuestionStep),
66 Decision(DecisionStep),
67 Action { name: String },
68 End,
69}
70
71#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
73pub struct QAFlowSpec {
74 pub id: String,
75 pub title: String,
76 pub version: String,
77 pub entry: StepId,
78 pub steps: BTreeMap<StepId, StepSpec>,
79 #[serde(skip_serializing_if = "Option::is_none")]
80 pub policies: Option<FlowPolicy>,
81}