db_pool/common/config/
postgres.rs1pub struct PrivilegedPostgresConfig {
3 pub(crate) username: String,
4 pub(crate) password: Option<String>,
5 pub(crate) host: String,
6 pub(crate) port: u16,
7}
8
9impl PrivilegedPostgresConfig {
10 const DEFAULT_USERNAME: &'static str = "postgres";
11 const DEFAULT_PASSWORD: Option<String> = None;
12 const DEFAULT_HOST: &'static str = "localhost";
13 const DEFAULT_PORT: u16 = 5432;
14
15 #[must_use]
28 pub fn new() -> Self {
29 Self {
30 username: Self::DEFAULT_USERNAME.to_owned(),
31 password: Self::DEFAULT_PASSWORD,
32 host: Self::DEFAULT_HOST.to_owned(),
33 port: Self::DEFAULT_PORT,
34 }
35 }
36
37 pub fn from_env() -> Result<Self, Error> {
49 use std::env;
50
51 let username = env::var("POSTGRES_USERNAME").unwrap_or(Self::DEFAULT_USERNAME.to_owned());
52 let password = env::var("POSTGRES_PASSWORD").ok();
53 let host = env::var("POSTGRES_HOST").unwrap_or(Self::DEFAULT_HOST.to_owned());
54 let port = env::var("POSTGRES_PORT")
55 .map_or(Ok(Self::DEFAULT_PORT), |port| port.parse())
56 .map_err(Error::InvalidPort)?;
57
58 Ok(Self {
59 username,
60 password,
61 host,
62 port,
63 })
64 }
65
66 #[must_use]
75 pub fn username(self, value: String) -> Self {
76 Self {
77 username: value,
78 ..self
79 }
80 }
81
82 #[must_use]
91 pub fn password(self, value: Option<String>) -> Self {
92 Self {
93 password: value,
94 ..self
95 }
96 }
97
98 #[must_use]
106 pub fn host(self, value: String) -> Self {
107 Self {
108 host: value,
109 ..self
110 }
111 }
112
113 #[must_use]
121 pub fn port(self, value: u16) -> Self {
122 Self {
123 port: value,
124 ..self
125 }
126 }
127
128 pub(crate) fn default_connection_url(&self) -> String {
129 let Self {
130 username,
131 password,
132 host,
133 port,
134 } = self;
135 if let Some(password) = password {
136 format!("postgres://{username}:{password}@{host}:{port}")
137 } else {
138 format!("postgres://{username}@{host}:{port}")
139 }
140 }
141
142 pub(crate) fn privileged_database_connection_url(&self, db_name: &str) -> String {
143 let Self {
144 username,
145 password,
146 host,
147 port,
148 } = self;
149 if let Some(password) = password {
150 format!("postgres://{username}:{password}@{host}:{port}/{db_name}")
151 } else {
152 format!("postgres://{username}@{host}:{port}/{db_name}")
153 }
154 }
155
156 pub(crate) fn restricted_database_connection_url(
157 &self,
158 username: &str,
159 password: Option<&str>,
160 db_name: &str,
161 ) -> String {
162 let Self { host, port, .. } = self;
163 if let Some(password) = password {
164 format!("postgres://{username}:{password}@{host}:{port}/{db_name}")
165 } else {
166 format!("postgres://{username}@{host}:{port}/{db_name}")
167 }
168 }
169}
170
171#[derive(Debug)]
172pub enum Error {
173 InvalidPort(std::num::ParseIntError),
174}
175
176impl Default for PrivilegedPostgresConfig {
177 fn default() -> Self {
178 Self::new()
179 }
180}
181
182#[cfg(feature = "postgres")]
183impl From<PrivilegedPostgresConfig> for r2d2_postgres::postgres::Config {
184 fn from(value: PrivilegedPostgresConfig) -> Self {
185 let PrivilegedPostgresConfig {
186 username,
187 password,
188 host,
189 port,
190 } = value;
191
192 let mut config = Self::new();
193
194 config
195 .user(username.as_str())
196 .host(host.as_str())
197 .port(port);
198
199 if let Some(password) = password {
200 config.password(password.as_str());
201 }
202
203 config
204 }
205}
206
207#[cfg(feature = "sqlx-postgres")]
208impl From<PrivilegedPostgresConfig> for sqlx::postgres::PgConnectOptions {
209 fn from(value: PrivilegedPostgresConfig) -> Self {
210 let PrivilegedPostgresConfig {
211 username,
212 password,
213 host,
214 port,
215 } = value;
216
217 let opts = Self::new()
218 .username(username.as_str())
219 .host(host.as_str())
220 .port(port);
221
222 if let Some(password) = password {
223 opts.password(password.as_str())
224 } else {
225 opts
226 }
227 }
228}
229
230#[cfg(feature = "tokio-postgres")]
231impl From<PrivilegedPostgresConfig> for tokio_postgres::Config {
232 fn from(value: PrivilegedPostgresConfig) -> Self {
233 let PrivilegedPostgresConfig {
234 username,
235 password,
236 host,
237 port,
238 } = value;
239
240 let mut config = Self::new();
241
242 config
243 .user(username.as_str())
244 .host(host.as_str())
245 .port(port);
246
247 if let Some(password) = password {
248 config.password(password.as_str());
249 }
250
251 config
252 }
253}