1use crate::spec::question::QuestionSpec;
2use crate::spec::validation::CrossFieldValidation;
3use crate::store::StoreOp;
4use schemars::JsonSchema;
5use serde::{Deserialize, Serialize};
6
7#[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}
15
16#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, JsonSchema, Default)]
18pub struct ProgressPolicy {
19 #[serde(default)]
20 pub skip_answered: bool,
21 #[serde(default)]
22 pub autofill_defaults: bool,
23 #[serde(default)]
24 pub treat_default_as_answered: bool,
25}
26
27#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
29pub struct SecretsPolicy {
30 #[serde(default)]
31 pub enabled: bool,
32 #[serde(default)]
33 pub read_enabled: bool,
34 #[serde(default)]
35 pub write_enabled: bool,
36 #[serde(default, skip_serializing_if = "Vec::is_empty")]
37 pub allow: Vec<String>,
38 #[serde(default, skip_serializing_if = "Vec::is_empty")]
39 pub deny: Vec<String>,
40}
41
42#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
44pub struct FormSpec {
45 pub id: String,
46 pub title: String,
47 pub version: String,
48 #[serde(skip_serializing_if = "Option::is_none")]
49 pub description: Option<String>,
50 #[serde(skip_serializing_if = "Option::is_none")]
51 pub presentation: Option<FormPresentation>,
52 #[serde(skip_serializing_if = "Option::is_none")]
53 pub progress_policy: Option<ProgressPolicy>,
54 #[serde(skip_serializing_if = "Option::is_none")]
55 pub secrets_policy: Option<SecretsPolicy>,
56 #[serde(default, skip_serializing_if = "Vec::is_empty")]
57 pub store: Vec<StoreOp>,
58 #[serde(default, skip_serializing_if = "Vec::is_empty")]
59 pub validations: Vec<CrossFieldValidation>,
60 pub questions: Vec<QuestionSpec>,
61}