Skip to main content

haste_repository/
config.rs

1//! Repository configuration and construction.
2//!
3//! Lives here rather than in each binary so the server and the worker connect
4//! to the same store described the same way — a second copy of these types is
5//! a second thing to keep in step, and the two drifting apart is how a worker
6//! ends up indexing into somewhere the server never reads.
7
8use std::sync::Arc;
9
10use haste_fhir_model::r4::generated::terminology::IssueType;
11use haste_fhir_operation_error::OperationOutcomeError;
12use serde::{Deserialize, Serialize};
13
14use crate::pg::PGConnection;
15
16/// Where the FHIR server stores its resources.
17#[derive(Debug, Clone, Deserialize, Serialize)]
18#[serde(tag = "backend", rename_all = "snake_case")]
19pub enum RepoConfig {
20    Postgres(PostgresRepoConfig),
21}
22
23#[derive(Debug, Clone, Deserialize, Serialize)]
24pub struct PostgresRepoConfig {
25    pub database_url: String,
26    pub max_connections: u32,
27}
28
29impl Default for PostgresRepoConfig {
30    fn default() -> Self {
31        Self {
32            database_url: "postgresql://postgres:postgres@127.0.0.1/haste_health".to_string(),
33            max_connections: 20,
34        }
35    }
36}
37
38impl Default for RepoConfig {
39    fn default() -> Self {
40        RepoConfig::Postgres(PostgresRepoConfig::default())
41    }
42}
43
44/// Opens a connection pool for `config`.
45///
46/// # Errors
47///
48/// Returns an error if the pool cannot open its first connection — an
49/// unreachable host, bad credentials, or a malformed `database_url`.
50pub async fn create_repo(config: &RepoConfig) -> Result<Arc<PGConnection>, OperationOutcomeError> {
51    match config {
52        RepoConfig::Postgres(pg_config) => {
53            let pool = sqlx::postgres::PgPoolOptions::new()
54                .max_connections(pg_config.max_connections)
55                .connect(&pg_config.database_url)
56                .await
57                .map_err(|e| {
58                    OperationOutcomeError::fatal(
59                        IssueType::exception(),
60                        format!("Failed to connect to the repository database: {e}"),
61                    )
62                })?;
63
64            Ok(Arc::new(PGConnection::pool(pool)))
65        }
66    }
67}