shuttle_common/models/
resource.rs

1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3
4#[derive(Clone, Debug, Serialize, Deserialize)]
5#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
6#[typeshare::typeshare]
7pub struct ProvisionResourceRequest {
8    /// The type of this resource
9    pub r#type: ResourceType,
10    /// The config used when creating this resource.
11    /// Use `Self::r#type` to know how to parse this data.
12    pub config: Value,
13}
14
15/// Helper for deserializing
16#[derive(Deserialize)]
17#[serde(untagged)] // Try deserializing as a Shuttle resource, fall back to a custom value
18pub enum ResourceInput {
19    Shuttle(ProvisionResourceRequest),
20    Custom(Value),
21}
22
23/// The resource state represents the stage of the provisioning process the resource is in.
24#[derive(
25    Debug, Clone, PartialEq, Eq, strum::Display, strum::EnumString, Serialize, Deserialize,
26)]
27#[serde(rename_all = "lowercase")]
28#[strum(serialize_all = "lowercase")]
29#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
30#[typeshare::typeshare]
31pub enum ResourceState {
32    Authorizing,
33    Provisioning,
34    Failed,
35    Ready,
36    Deleting,
37    Deleted,
38
39    /// Forward compatibility
40    #[cfg(feature = "unknown-variants")]
41    #[doc(hidden)]
42    #[typeshare(skip)]
43    #[serde(untagged, skip_serializing)]
44    #[strum(default, to_string = "Unknown: {0}")]
45    Unknown(String),
46}
47
48#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
49#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
50#[typeshare::typeshare]
51pub struct ResourceResponse {
52    pub r#type: ResourceType,
53    pub state: ResourceState,
54    /// The config used when creating this resource. Use the `r#type` to know how to parse this data.
55    pub config: Value,
56    /// The output type for this resource, if state is Ready. Use the `r#type` to know how to parse this data.
57    pub output: Value,
58}
59
60#[derive(Debug, Serialize, Deserialize)]
61#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
62#[typeshare::typeshare]
63pub struct ResourceListResponse {
64    pub resources: Vec<ResourceResponse>,
65}
66
67#[derive(
68    Clone,
69    Debug,
70    Deserialize,
71    Serialize,
72    Eq,
73    PartialEq,
74    strum::AsRefStr,
75    strum::Display,
76    strum::EnumString,
77)]
78#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
79#[typeshare::typeshare]
80// is a flat enum instead of nested enum to allow typeshare
81pub enum ResourceType {
82    #[strum(to_string = "database::shared::postgres")]
83    #[serde(rename = "database::shared::postgres")]
84    DatabaseSharedPostgres,
85    #[strum(to_string = "database::aws_rds::postgres")]
86    #[serde(rename = "database::aws_rds::postgres")]
87    DatabaseAwsRdsPostgres,
88    #[strum(to_string = "database::aws_rds::mysql")]
89    #[serde(rename = "database::aws_rds::mysql")]
90    DatabaseAwsRdsMySql,
91    #[strum(to_string = "database::aws_rds::mariadb")]
92    #[serde(rename = "database::aws_rds::mariadb")]
93    DatabaseAwsRdsMariaDB,
94    /// (Will probably be removed)
95    #[strum(to_string = "secrets")]
96    #[serde(rename = "secrets")]
97    Secrets,
98    /// Local provisioner only
99    #[strum(to_string = "container")]
100    #[serde(rename = "container")]
101    Container,
102
103    /// Forward compatibility
104    #[cfg(feature = "unknown-variants")]
105    #[doc(hidden)]
106    #[typeshare(skip)]
107    #[serde(untagged, skip_serializing)]
108    #[strum(default, to_string = "Unknown: {0}")]
109    Unknown(String),
110}
111
112#[cfg(test)]
113mod tests {
114    use std::str::FromStr;
115
116    use super::*;
117
118    #[test]
119    fn to_string_and_back() {
120        let inputs = [
121            ResourceType::DatabaseSharedPostgres,
122            ResourceType::Secrets,
123            ResourceType::Container,
124        ];
125
126        for input in inputs {
127            let actual = ResourceType::from_str(input.as_ref()).unwrap();
128            assert_eq!(input, actual, ":{} should map back to itself", input);
129        }
130    }
131}