Skip to main content

valence_backend_postgres/
config.rs

1//! Postgres connection configuration and builder.
2
3use valence_core::error::{Error, Result};
4
5/// Environment variable for Postgres connection URL.
6pub const URL_ENV: &str = "DATABASE_URL";
7
8/// Builder for [`super::backend::PostgresBackend`].
9#[derive(Debug, Clone, Default)]
10pub struct PostgresBackendBuilder {
11    url: Option<String>,
12}
13
14impl PostgresBackendBuilder {
15    /// Empty builder; set fields or call [`Self::from_env_defaults`].
16    pub fn new() -> Self {
17        Self::default()
18    }
19
20    /// Fill unset URL from `DATABASE_URL`.
21    #[must_use]
22    pub fn from_env_defaults(mut self) -> Self {
23        if self.url.is_none() {
24            self.url = postgres_url_from_env();
25        }
26        self
27    }
28
29    /// Postgres connection URL.
30    #[must_use]
31    pub fn url(mut self, url: impl Into<String>) -> Self {
32        self.url = Some(url.into());
33        self
34    }
35
36    /// Whether a URL is set explicitly or resolvable via env defaults.
37    pub fn has_url(&self) -> bool {
38        self.url.is_some() || postgres_url_from_env().is_some()
39    }
40
41    /// Resolve URL without connecting.
42    ///
43    /// # Errors
44    ///
45    /// Returns [`Error::Internal`] when no URL is set and `DATABASE_URL` is unset or empty.
46    pub fn resolve(self) -> Result<String> {
47        let builder = self.from_env_defaults();
48        builder
49            .url
50            .ok_or_else(|| Error::Internal(format!("{URL_ENV} not set for postgres adapter")))
51    }
52
53    /// Connect and return a [`super::backend::PostgresBackend`].
54    ///
55    /// # Errors
56    ///
57    /// Returns an error if URL resolution or the database connection fails.
58    pub async fn build(self) -> Result<super::backend::PostgresBackend> {
59        let url = self.resolve()?;
60        super::backend::PostgresBackend::connect(&url).await
61    }
62}
63
64fn postgres_url_from_env() -> Option<String> {
65    std::env::var(URL_ENV)
66        .ok()
67        .map(|v| v.trim().to_string())
68        .filter(|v| !v.is_empty())
69}