tain/postgres/
postgres_config.rs1use std::{collections::HashMap, path::PathBuf, str::FromStr};
2
3use anyhow::{Result, anyhow};
4use dotenvy::{dotenv, vars};
5use typed_builder::TypedBuilder;
6
7use crate::Mount;
8
9#[derive(Clone, TypedBuilder)]
10pub struct PostgresConfig {
11 #[builder(setter(into))]
12 pub container_name: String,
13
14 #[builder(default, setter(strip_option), setter(into))]
15 pub db: Option<String>,
16
17 #[builder(default, setter(strip_option), setter(into))]
18 pub password: Option<String>,
19
20 #[builder(default, setter(strip_option))]
21 pub data: Option<Mount>,
22
23 #[builder(default = 5432)]
24 pub port: u16,
25}
26
27impl PostgresConfig {
28 pub fn from_env() -> Result<Self> {
29 #[cfg(not(target_os = "windows"))]
30 fn data_host(vars: &HashMap<String, String>) -> Result<String> {
31 Ok(vars
32 .get("POSTGRES_DATA_HOST")
33 .ok_or(anyhow!("No POSTGRES_DATA_HOST in .env"))?
34 .to_string())
35 }
36
37 #[cfg(target_os = "windows")]
38 fn data_host(vars: &HashMap<String, String>) -> Result<String> {
39 let home = dirs::home_dir().expect("No HOME");
40 let host = vars.get("POSTGRES_DATA_HOST").ok_or(anyhow!("No POSTGRES_DATA_HOST in .env"))?;
41 let host = format!("{}{host}", home.display());
42 Ok(host)
43 }
44
45 dotenv()?;
46
47 let vars: HashMap<String, String> = vars().collect();
48
49 let db = vars.get("POSTGRES_DB").ok_or(anyhow!("No POSTGRES_DB in .env"))?;
50 let password = vars.get("POSTGRES_PASSWORD").ok_or(anyhow!("No POSTGRES_PASSWORD in .env"))?;
51 let port = vars.get("POSTGRES_PORT").ok_or(anyhow!("No POSTGRES_PORT in .env"))?;
52
53 let data_container = vars
54 .get("POSTGRES_DATA_CONTAINER")
55 .ok_or(anyhow!("No POSTGRES_DATA_CONTAINER in .env"))?;
56 let container_name = vars
57 .get("POSTGRES_CONTAINER_NAME")
58 .ok_or(anyhow!("No POSTGRES_CONTAINER_NAME in .env"))?;
59
60 let new = Self::builder()
61 .container_name(container_name)
62 .db(db)
63 .password(password)
64 .data(Mount {
65 host: PathBuf::from_str(&data_host(&vars)?)?,
66 container: PathBuf::from_str(data_container)?,
67 })
68 .port(port.parse()?)
69 .build();
70
71 Ok(new)
72 }
73}