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#[typeshare::typeshare]
32pub struct DatabaseInfo {
33 engine: String,
34 role_name: String,
35 role_password: String,
36 database_name: String,
37 port: String,
38 hostname: String,
39 instance_name: Option<String>,
42}
43
44impl DatabaseInfo {
45 pub fn new(
46 engine: String,
47 role_name: String,
48 role_password: String,
49 database_name: String,
50 port: String,
51 hostname: String,
52 instance_name: Option<String>,
53 ) -> Self {
54 Self {
55 engine,
56 role_name,
57 role_password,
58 database_name,
59 port,
60 hostname,
61 instance_name,
62 }
63 }
64
65 pub fn connection_string(&self, show_password: bool) -> String {
67 format!(
68 "{}://{}:{}@{}:{}/{}",
69 self.engine,
70 self.role_name,
71 if show_password {
72 &self.role_password
73 } else {
74 "********"
75 },
76 self.hostname,
77 self.port,
78 self.database_name,
79 )
80 }
81
82 pub fn role_name(&self) -> String {
83 self.role_name.to_string()
84 }
85
86 pub fn database_name(&self) -> String {
87 self.database_name.to_string()
88 }
89
90 pub fn instance_name(&self) -> Option<String> {
91 self.instance_name.clone()
92 }
93}
94
95impl std::fmt::Debug for DatabaseInfo {
97 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
98 write!(f, "DatabaseInfo {{ {:?} }}", self.connection_string(false))
99 }
100}
101
102#[derive(Serialize, Deserialize)]
104pub struct ContainerRequest {
105 pub project_name: String,
106 pub container_name: String,
108 pub image: String,
110 pub port: String,
112 pub env: Vec<String>,
114}
115
116#[derive(Serialize, Deserialize)]
118pub struct ContainerResponse {
119 pub host_port: String,
122}
123
124pub fn semvers_are_compatible(a: &semver::Version, b: &semver::Version) -> bool {
127 if a.major != 0 || b.major != 0 {
128 a.major == b.major
129 } else if a.minor != 0 || b.minor != 0 {
130 a.minor == b.minor
131 } else {
132 a.patch == b.patch
133 }
134}
135
136#[cfg(test)]
137mod tests {
138 use std::str::FromStr;
139
140 #[test]
141 fn semver_compatibility_check_works() {
142 let semver_tests = &[
143 ("1.0.0", "1.0.0", true),
144 ("1.8.0", "1.0.0", true),
145 ("0.1.0", "0.2.1", false),
146 ("0.9.0", "0.2.0", false),
147 ];
148 for (version_a, version_b, are_compatible) in semver_tests {
149 let version_a = semver::Version::from_str(version_a).unwrap();
150 let version_b = semver::Version::from_str(version_b).unwrap();
151 assert_eq!(
152 super::semvers_are_compatible(&version_a, &version_b),
153 *are_compatible
154 );
155 }
156 }
157}