Skip to main content

qa_spec/spec/
form.rs

1use crate::spec::question::QuestionSpec;
2use crate::spec::validation::CrossFieldValidation;
3use crate::store::StoreOp;
4use schemars::JsonSchema;
5use serde::{Deserialize, Serialize};
6
7/// Presentation hints for a form.
8#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
9pub struct FormPresentation {
10    #[serde(default, skip_serializing_if = "Option::is_none")]
11    pub intro: Option<String>,
12    #[serde(default, skip_serializing_if = "Option::is_none")]
13    pub theme: Option<String>,
14    #[serde(default, skip_serializing_if = "Option::is_none")]
15    pub default_locale: Option<String>,
16}
17
18/// Execution policies shared by question navigation.
19#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, JsonSchema)]
20pub struct ProgressPolicy {
21    #[serde(default)]
22    pub skip_answered: bool,
23    #[serde(default)]
24    pub autofill_defaults: bool,
25    #[serde(default)]
26    pub treat_default_as_answered: bool,
27}
28
29impl Default for ProgressPolicy {
30    fn default() -> Self {
31        Self {
32            skip_answered: true,
33            autofill_defaults: false,
34            treat_default_as_answered: false,
35        }
36    }
37}
38
39/// Secrets policy for the form.
40#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
41pub struct SecretsPolicy {
42    #[serde(default)]
43    pub enabled: bool,
44    #[serde(default)]
45    pub read_enabled: bool,
46    #[serde(default)]
47    pub write_enabled: bool,
48    #[serde(default, skip_serializing_if = "Vec::is_empty")]
49    pub allow: Vec<String>,
50    #[serde(default, skip_serializing_if = "Vec::is_empty")]
51    pub deny: Vec<String>,
52}
53
54/// Include reference for composing forms from a registry.
55#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
56pub struct IncludeSpec {
57    pub form_ref: String,
58    #[serde(default, skip_serializing_if = "Option::is_none")]
59    pub prefix: Option<String>,
60}
61
62/// Top-level QA form definition.
63#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
64pub struct FormSpec {
65    pub id: String,
66    pub title: String,
67    pub version: String,
68    #[serde(skip_serializing_if = "Option::is_none")]
69    pub description: Option<String>,
70    #[serde(skip_serializing_if = "Option::is_none")]
71    pub presentation: Option<FormPresentation>,
72    #[serde(skip_serializing_if = "Option::is_none")]
73    pub progress_policy: Option<ProgressPolicy>,
74    #[serde(skip_serializing_if = "Option::is_none")]
75    pub secrets_policy: Option<SecretsPolicy>,
76    #[serde(default, skip_serializing_if = "Vec::is_empty")]
77    pub store: Vec<StoreOp>,
78    #[serde(default, skip_serializing_if = "Vec::is_empty")]
79    pub validations: Vec<CrossFieldValidation>,
80    #[serde(default, skip_serializing_if = "Vec::is_empty")]
81    pub includes: Vec<IncludeSpec>,
82    pub questions: Vec<QuestionSpec>,
83}