1use std::path::PathBuf;
2
3use sqlx::{postgres::PgConnectOptions, ConnectOptions, PgConnection};
4
5#[derive(Debug, Clone)]
6pub struct Config {
7 pub database_connect_options: Option<PgConnectOptions>,
8
9 pub migrations_dir: PathBuf,
10 pub templates_dir: Option<PathBuf>,
11
12 pub only_up: bool,
14}
15
16impl Config {
17 pub async fn connect(&self) -> Result<PgConnection, ConnectError> {
18 if let Some(opts) = &self.database_connect_options {
19 opts.connect().await.map_err(ConnectError::Connect)
20 } else {
21 Err(ConnectError::NotConfigured)
22 }
23 }
24}
25
26#[derive(thiserror::Error, Debug)]
27pub enum ConnectError {
28 #[error("no database configured")]
29 NotConfigured,
30
31 #[error("failed to connect to database: {0}")]
32 Connect(sqlx::Error),
33}
34
35#[cfg(test)]
36mod tests {
37 use crate::testing::*;
38
39 use super::*;
40
41 #[tokio::test]
42 async fn connect() {
43 let env = TestEnv::new().await.unwrap();
44
45 let config = env.config();
46
47 config.connect().await.unwrap();
48 }
49
50 #[tokio::test]
51 async fn not_configured() {
52 let env = TestEnv::new().await.unwrap();
53
54 let mut config = env.config();
55 config.database_connect_options = None;
56
57 let res = config.connect().await;
58 assert!(res.is_err());
59
60 match res.unwrap_err() {
61 ConnectError::NotConfigured => (),
62 err => panic!("Unexpected error: {:?}", err),
63 };
64 }
65
66 #[tokio::test]
67 async fn connect_error() {
68 let env = TestEnv::new().await.unwrap();
69
70 let mut config = env.config();
71 config.database_connect_options = config
72 .database_connect_options
73 .map(|opts| opts.database("__not_a_squill_test"));
74
75 let res = config.connect().await;
76 assert!(res.is_err());
77
78 match res.unwrap_err() {
79 ConnectError::Connect(_) => (),
80 err => panic!("Unexpected error: {:?}", err),
81 };
82 }
83}