use super::ServerError;
use crate::config::RullstConfig;
use std::collections::HashMap;
use std::path::Path;
pub(crate) fn resolve_database_url(
explicit: Option<&str>,
environment: impl Fn(&str) -> Result<Option<String>, ServerError>,
dotenv: &HashMap<String, String>,
config: &RullstConfig,
) -> Result<Option<String>, ServerError> {
if let Some(url) = explicit {
return Ok(Some(url.to_string()));
}
if let Some(url) = environment("DATABASE_URL")? {
return Ok(Some(url));
}
if let Some(url) = dotenv.get("DATABASE_URL") {
return Ok(Some(url.clone()));
}
Ok(config.database.url.clone())
}
#[cfg(feature = "orm")]
pub(crate) async fn resolve_project_database_url(
project_dir: &Path,
explicit: Option<&str>,
environment: impl Fn(&str) -> Result<Option<String>, ServerError>,
) -> Result<Option<String>, ServerError> {
let dotenv = load_dotenv_file(&project_dir.join(".env")).await?;
let config = load_config_file(&project_dir.join("Rullst.toml")).await?;
resolve_database_url(explicit, environment, &dotenv, &config)
}
pub(crate) async fn load_dotenv_file(path: &Path) -> Result<HashMap<String, String>, ServerError> {
if !path.exists() {
return Ok(HashMap::new());
}
let content = tokio::fs::read_to_string(path).await?;
super::builder::parse_dotenv(&content)
}
pub(crate) async fn load_config_file(path: &Path) -> Result<RullstConfig, ServerError> {
if !path.exists() {
return Ok(RullstConfig::new());
}
let content = tokio::fs::read_to_string(path).await.map_err(|error| {
ServerError::Configuration(crate::config::ConfigError::Read(error.to_string()).to_string())
})?;
RullstConfig::from_toml(&content).map_err(|error| ServerError::Configuration(error.to_string()))
}