Skip to main content

greentic_bundle/setup/
mod.rs

1pub mod backend;
2pub mod legacy_formspec;
3pub mod persist;
4pub mod qa_bridge;
5
6use std::collections::BTreeMap;
7
8use anyhow::Result;
9use serde::{Deserialize, Serialize};
10use serde_json::Value;
11
12pub const SETUP_STATE_DIR: &str = "state/setup";
13pub const SETUP_STATE_SCHEMA_VERSION: u32 = 1;
14
15#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
16pub struct FormSpec {
17    pub id: String,
18    pub title: String,
19    pub version: String,
20    #[serde(skip_serializing_if = "Option::is_none")]
21    pub description: Option<String>,
22    pub questions: Vec<QuestionSpec>,
23}
24
25#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
26pub struct QuestionSpec {
27    pub id: String,
28    pub kind: QuestionKind,
29    pub title: String,
30    #[serde(skip_serializing_if = "Option::is_none")]
31    pub description: Option<String>,
32    pub required: bool,
33    #[serde(default, skip_serializing_if = "Vec::is_empty")]
34    pub choices: Vec<String>,
35    #[serde(skip_serializing_if = "Option::is_none")]
36    pub default_value: Option<Value>,
37    pub secret: bool,
38}
39
40#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
41#[serde(rename_all = "snake_case")]
42pub enum QuestionKind {
43    String,
44    Number,
45    Boolean,
46    Enum,
47}
48
49#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
50#[serde(tag = "type", rename_all = "snake_case")]
51pub enum SetupSpecInput {
52    Legacy {
53        spec: Value,
54    },
55    ProviderQa {
56        qa_output: Value,
57        #[serde(default)]
58        i18n: BTreeMap<String, String>,
59    },
60}
61
62#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
63pub struct PersistedSetupState {
64    pub schema_version: u32,
65    pub provider_id: String,
66    pub source_kind: String,
67    pub form: FormSpec,
68    pub normalized_answers: BTreeMap<String, Value>,
69    pub non_secret_config: BTreeMap<String, Value>,
70    pub secret_values: BTreeMap<String, Value>,
71}
72
73pub fn form_spec_from_input(
74    input: &SetupSpecInput,
75    provider_id: &str,
76) -> Result<(String, FormSpec)> {
77    match input {
78        SetupSpecInput::Legacy { spec } => {
79            let parsed = match spec {
80                Value::String(raw) => legacy_formspec::parse_setup_spec_str(raw)?,
81                value => legacy_formspec::parse_setup_spec_value(value.clone())?,
82            };
83            Ok((
84                "legacy".to_string(),
85                legacy_formspec::setup_spec_to_form_spec(&parsed, provider_id),
86            ))
87        }
88        SetupSpecInput::ProviderQa { qa_output, i18n } => Ok((
89            "provider_qa".to_string(),
90            qa_bridge::provider_qa_to_form_spec(qa_output, i18n, provider_id),
91        )),
92    }
93}