1use serde::{Deserialize, Serialize};
2
3use crate::Platform;
4
5#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
7#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
8#[serde(rename_all = "camelCase")]
9pub enum StackInputProvider {
10 Developer,
12 Deployer,
14}
15
16#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
18#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
19#[serde(rename_all = "camelCase")]
20pub enum StackInputKind {
21 String,
23 Secret,
25 Number,
27 Integer,
29 Boolean,
31 Enum,
33 StringList,
35}
36
37#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
39#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
40#[serde(rename_all = "camelCase")]
41pub struct StackInputEnvironmentMapping {
42 pub name: String,
44 #[serde(default, skip_serializing_if = "Option::is_none")]
46 pub target_resources: Option<Vec<String>>,
47 #[serde(rename = "type", default, skip_serializing_if = "Option::is_none")]
49 pub var_type: Option<StackInputEnvironmentVariableType>,
50}
51
52#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
54#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
55#[serde(rename_all = "lowercase")]
56pub enum StackInputEnvironmentVariableType {
57 Plain,
59 Secret,
61}
62
63#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
65#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
66#[serde(rename_all = "camelCase")]
67pub struct StackInputValidation {
68 #[serde(default, skip_serializing_if = "Option::is_none")]
70 pub min_length: Option<u32>,
71 #[serde(default, skip_serializing_if = "Option::is_none")]
73 pub max_length: Option<u32>,
74 #[serde(default, skip_serializing_if = "Option::is_none")]
76 pub pattern: Option<String>,
77 #[serde(default, skip_serializing_if = "Option::is_none")]
79 pub format: Option<String>,
80 #[serde(default, skip_serializing_if = "Option::is_none")]
82 pub min: Option<String>,
83 #[serde(default, skip_serializing_if = "Option::is_none")]
85 pub max: Option<String>,
86 #[serde(default, skip_serializing_if = "Option::is_none")]
88 pub values: Option<Vec<String>>,
89 #[serde(default, skip_serializing_if = "Option::is_none")]
91 pub min_items: Option<u32>,
92 #[serde(default, skip_serializing_if = "Option::is_none")]
94 pub max_items: Option<u32>,
95}
96
97#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
99#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
100#[serde(rename_all = "camelCase", tag = "type", content = "value")]
101pub enum StackInputDefaultValue {
102 String(String),
104 Number(String),
106 Boolean(bool),
108 StringList(Vec<String>),
110}
111
112#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
114#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
115#[serde(rename_all = "camelCase")]
116pub struct StackInputDefinition {
117 pub id: String,
119 pub kind: StackInputKind,
121 pub provided_by: Vec<StackInputProvider>,
123 pub required: bool,
125 pub label: String,
127 pub description: String,
129 #[serde(default, skip_serializing_if = "Option::is_none")]
131 pub placeholder: Option<String>,
132 #[serde(default, skip_serializing_if = "Option::is_none")]
134 pub default: Option<StackInputDefaultValue>,
135 #[serde(default, skip_serializing_if = "Option::is_none")]
137 pub platforms: Option<Vec<Platform>>,
138 #[serde(default, skip_serializing_if = "Option::is_none")]
140 pub validation: Option<StackInputValidation>,
141 #[serde(default, skip_serializing_if = "Vec::is_empty")]
143 pub env: Vec<StackInputEnvironmentMapping>,
144}
145
146impl StackInputDefinition {
147 #[doc(hidden)]
153 pub fn deployer_boolean(
154 id: &str,
155 label: &str,
156 description: &str,
157 default: Option<bool>,
158 ) -> Self {
159 Self {
160 id: id.to_string(),
161 kind: StackInputKind::Boolean,
162 provided_by: vec![StackInputProvider::Deployer],
163 required: default.is_none(),
164 label: label.to_string(),
165 description: description.to_string(),
166 placeholder: None,
167 default: default.map(StackInputDefaultValue::Boolean),
168 platforms: None,
169 validation: None,
170 env: Vec::new(),
171 }
172 }
173}
174
175pub fn find_boolean_gate_input<'a>(
180 inputs: &'a [StackInputDefinition],
181 input_id: &str,
182) -> Result<&'a StackInputDefinition, GateInputIssue> {
183 let input = inputs
184 .iter()
185 .find(|input| input.id == input_id)
186 .ok_or(GateInputIssue::Undeclared)?;
187 if input.kind != StackInputKind::Boolean {
188 return Err(GateInputIssue::NotBoolean(input.kind.clone()));
189 }
190 Ok(input)
191}
192
193#[derive(Debug, Clone, PartialEq, Eq)]
196pub enum GateInputIssue {
197 Undeclared,
199 NotBoolean(StackInputKind),
201}