db_pool/common/config/
mysql.rs1#[derive(Clone)]
3pub struct PrivilegedMySQLConfig {
4 pub(crate) username: String,
5 pub(crate) password: Option<String>,
6 pub(crate) host: String,
7 pub(crate) port: u16,
8}
9
10impl PrivilegedMySQLConfig {
11 const DEFAULT_USERNAME: &'static str = "root";
12 const DEFAULT_PASSWORD: Option<String> = None;
13 const DEFAULT_HOST: &'static str = "localhost";
14 const DEFAULT_PORT: u16 = 3306;
15
16 #[must_use]
29 pub fn new() -> Self {
30 Self {
31 username: Self::DEFAULT_USERNAME.to_owned(),
32 password: Self::DEFAULT_PASSWORD,
33 host: Self::DEFAULT_HOST.to_owned(),
34 port: Self::DEFAULT_PORT,
35 }
36 }
37
38 pub fn from_env() -> Result<Self, Error> {
50 use std::env;
51
52 let username = env::var("MYSQL_USERNAME").unwrap_or(Self::DEFAULT_USERNAME.to_owned());
53 let password = env::var("MYSQL_PASSWORD").ok();
54 let host = env::var("MYSQL_HOST").unwrap_or(Self::DEFAULT_HOST.to_owned());
55 let port = env::var("MYSQL_PORT")
56 .map_or(Ok(Self::DEFAULT_PORT), |port| port.parse())
57 .map_err(Error::InvalidPort)?;
58
59 Ok(Self {
60 username,
61 password,
62 host,
63 port,
64 })
65 }
66
67 #[must_use]
76 pub fn username(self, value: String) -> Self {
77 Self {
78 username: value,
79 ..self
80 }
81 }
82
83 #[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!("mysql://{username}:{password}@{host}:{port}")
137 } else {
138 format!("mysql://{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 ..
149 } = self;
150 if let Some(password) = password {
151 format!("mysql://{username}:{password}@{host}:{port}/{db_name}")
152 } else {
153 format!("mysql://{username}@{host}:{port}/{db_name}")
154 }
155 }
156
157 pub(crate) fn restricted_database_connection_url(
158 &self,
159 username: &str,
160 password: Option<&str>,
161 db_name: &str,
162 ) -> String {
163 let Self { host, port, .. } = self;
164 if let Some(password) = password {
165 format!("mysql://{username}:{password}@{host}:{port}/{db_name}")
166 } else {
167 format!("mysql://{username}@{host}:{port}/{db_name}")
168 }
169 }
170}
171
172#[derive(Debug)]
173pub enum Error {
174 InvalidPort(std::num::ParseIntError),
175}
176
177impl Default for PrivilegedMySQLConfig {
178 fn default() -> Self {
179 Self::new()
180 }
181}
182
183#[cfg(feature = "mysql")]
184impl From<PrivilegedMySQLConfig> for r2d2_mysql::mysql::OptsBuilder {
185 fn from(value: PrivilegedMySQLConfig) -> Self {
186 Self::new()
187 .user(Some(value.username.clone()))
188 .pass(value.password.clone())
189 .ip_or_hostname(Some(value.host.clone()))
190 .tcp_port(value.port)
191 }
192}
193
194#[cfg(feature = "mysql")]
195impl From<PrivilegedMySQLConfig> for r2d2_mysql::mysql::Opts {
196 fn from(value: PrivilegedMySQLConfig) -> Self {
197 r2d2_mysql::mysql::OptsBuilder::from(value).into()
198 }
199}
200
201#[cfg(feature = "sqlx-mysql")]
202impl From<PrivilegedMySQLConfig> for sqlx::mysql::MySqlConnectOptions {
203 fn from(value: PrivilegedMySQLConfig) -> Self {
204 let PrivilegedMySQLConfig {
205 username,
206 password,
207 host,
208 port,
209 } = value;
210
211 let opts = Self::new()
212 .username(username.as_str())
213 .host(host.as_str())
214 .port(port);
215
216 if let Some(password) = password {
217 opts.password(password.as_str())
218 } else {
219 opts
220 }
221 }
222}