1pub mod constants;
2#[cfg(feature = "models")]
3pub mod models;
4pub mod secrets;
5#[cfg(feature = "tables")]
6pub mod tables;
7pub mod templates;
8
9use serde::{Deserialize, Serialize};
10
11#[derive(Clone, Deserialize, Serialize, Default)]
15pub struct DbInput {
16 pub local_uri: Option<String>,
17 pub db_name: Option<String>,
19}
20
21#[derive(Deserialize, Serialize)]
23#[serde(untagged)]
24pub enum DatabaseResource {
25 ConnectionString(String),
26 Info(DatabaseInfo),
27}
28
29#[derive(Clone, Serialize, Deserialize)]
31#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
32#[typeshare::typeshare]
33pub struct DatabaseInfo {
34 engine: String,
35 role_name: String,
36 role_password: String,
37 database_name: String,
38 port: String,
39 hostname: String,
40 instance_name: Option<String>,
43}
44
45impl DatabaseInfo {
46 pub fn new(
47 engine: String,
48 role_name: String,
49 role_password: String,
50 database_name: String,
51 port: String,
52 hostname: String,
53 instance_name: Option<String>,
54 ) -> Self {
55 Self {
56 engine,
57 role_name,
58 role_password,
59 database_name,
60 port,
61 hostname,
62 instance_name,
63 }
64 }
65
66 pub fn connection_string(&self, show_password: bool) -> String {
68 format!(
69 "{}://{}:{}@{}:{}/{}",
70 self.engine,
71 self.role_name,
72 if show_password {
73 &self.role_password
74 } else {
75 "********"
76 },
77 self.hostname,
78 self.port,
79 self.database_name,
80 )
81 }
82
83 pub fn role_name(&self) -> String {
84 self.role_name.to_string()
85 }
86
87 pub fn database_name(&self) -> String {
88 self.database_name.to_string()
89 }
90
91 pub fn instance_name(&self) -> Option<String> {
92 self.instance_name.clone()
93 }
94}
95
96impl std::fmt::Debug for DatabaseInfo {
98 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
99 write!(f, "DatabaseInfo {{ {:?} }}", self.connection_string(false))
100 }
101}
102
103#[derive(Serialize, Deserialize)]
105pub struct ContainerRequest {
106 pub project_name: String,
107 pub container_name: String,
109 pub image: String,
111 pub port: String,
113 pub env: Vec<String>,
115}
116
117#[derive(Serialize, Deserialize)]
119pub struct ContainerResponse {
120 pub host_port: String,
123}
124
125pub fn semvers_are_compatible(a: &semver::Version, b: &semver::Version) -> bool {
128 if a.major != 0 || b.major != 0 {
129 a.major == b.major
130 } else if a.minor != 0 || b.minor != 0 {
131 a.minor == b.minor
132 } else {
133 a.patch == b.patch
134 }
135}
136
137#[cfg(test)]
138mod tests {
139 use std::str::FromStr;
140
141 #[test]
142 fn semver_compatibility_check_works() {
143 let semver_tests = &[
144 ("1.0.0", "1.0.0", true),
145 ("1.8.0", "1.0.0", true),
146 ("0.1.0", "0.2.1", false),
147 ("0.9.0", "0.2.0", false),
148 ];
149 for (version_a, version_b, are_compatible) in semver_tests {
150 let version_a = semver::Version::from_str(version_a).unwrap();
151 let version_b = semver::Version::from_str(version_b).unwrap();
152 assert_eq!(
153 super::semvers_are_compatible(&version_a, &version_b),
154 *are_compatible
155 );
156 }
157 }
158}