Skip to content

Commit

Permalink
update settings dir
Browse files Browse the repository at this point in the history
  • Loading branch information
robatipoor committed Feb 15, 2024
1 parent 228e8c0 commit 9ddb294
Show file tree
Hide file tree
Showing 11 changed files with 101 additions and 46 deletions.
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ log = "0.4.20"
log-derive = "0.4.1"
once_cell = "1.19.0"
openssl = "0.10.62"
project-root = "0.2.2"
rand = "0.8.5"
rand_core = { version = "0.6.4", features = ["std"] }
redis = { version = "0.24.0", features = ["tokio-comp"] }
Expand Down
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ To use this template as your project starting point, click "Use this template" a
### Running locally

```bash
./run.sh
./run
# open swagger panel
xdg-open http://127.0.0.1:8080/swagger-ui/
# manually testing your API routes with curl commands
Expand Down Expand Up @@ -92,6 +92,13 @@ cargo run --bin migration -- up -u $DATABASE_URL
```bash
planter postgres://username:password@localhost:5432/database_name\?sslmode=disable -o docs/schema.puml
```

## Run tests
```sh
# Execute all test projects.
./test
```

## License

Licensed under either of
Expand Down
File renamed without changes.
16 changes: 16 additions & 0 deletions src/configure/env.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use std::str::FromStr;

use super::Profile;
use config::ConfigError;

pub fn get_env_source(prefix: &str) -> config::Environment {
config::Environment::with_prefix(prefix)
.prefix_separator("__")
.separator("__")
}

pub fn get_profile() -> Result<Profile, config::ConfigError> {
std::env::var("APP_PROFILE")
.map(|env| Profile::from_str(&env).map_err(|e| ConfigError::Message(e.to_string())))
.unwrap_or_else(|_e| Ok(Profile::Dev))
}
36 changes: 25 additions & 11 deletions src/configure/mod.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use std::str::FromStr;

use ::tracing::info;
use config::ConfigError;
use config::{ConfigError, Environment};
use serde::Deserialize;

use crate::util;
use crate::util::dir::get_project_root;

use self::{
db::DatabaseConfig, email::EmailConfig, http::HttpClientConfig, redis::RedisConfig,
Expand All @@ -13,6 +13,7 @@ use self::{

pub mod db;
pub mod email;
pub mod env;
pub mod http;
pub mod redis;
pub mod secret;
Expand All @@ -36,27 +37,38 @@ pub struct AppConfig {
}

impl AppConfig {
pub fn read() -> Result<Self, config::ConfigError> {
let config_dir =
util::dir::root_dir("settings").map_err(|e| ConfigError::Message(e.to_string()))?;
pub fn read(env_src: Environment) -> Result<Self, config::ConfigError> {
let config_dir = get_settings_dir()?;
let profile = std::env::var("APP_PROFILE")
.map(|env| Profile::from_str(&env).map_err(|e| ConfigError::Message(e.to_string())))
.unwrap_or_else(|_e| Ok(Profile::Dev))?;
let profile_filename = format!("{profile}.toml");
let config = config::Config::builder()
.add_source(config::File::from(config_dir.join("base.toml")))
.add_source(config::File::from(config_dir.join(profile_filename)))
.add_source(
config::Environment::with_prefix("APP")
.prefix_separator("_")
.separator("__"),
)
.add_source(env_src)
.build()?;
info!("Successfully read config profile: {profile}.");
config.try_deserialize()
}
}

pub fn get_settings_dir() -> Result<std::path::PathBuf, ConfigError> {
Ok(
get_project_root()
.map_err(|e| ConfigError::Message(e.to_string()))?
.join("settings"),
)
}

pub fn get_static_dir() -> Result<std::path::PathBuf, ConfigError> {
Ok(
get_project_root()
.map_err(|e| ConfigError::Message(e.to_string()))?
.join("static"),
)
}

#[derive(
Debug, strum::Display, strum::EnumString, Deserialize, PartialEq, Eq, PartialOrd, Ord, Clone, Copy,
)]
Expand All @@ -76,11 +88,13 @@ pub enum Profile {
mod tests {
use std::convert::TryFrom;

use self::env::get_env_source;

pub use super::*;

#[test]
pub fn test_read_app_config() {
let _config = AppConfig::read().unwrap();
let _config = AppConfig::read(get_env_source("TEST_APP")).unwrap();
}

#[test]
Expand Down
18 changes: 9 additions & 9 deletions src/configure/secret.rs
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@
use std::fs;
use std::{fs, path::PathBuf};

use serde::Deserialize;

use crate::util;

#[derive(Debug, Deserialize, Clone)]
pub struct SecretConfig {
pub private_access_key: String,
pub public_access_key: String,
pub private_refresh_key: String,
pub public_refresh_key: String,
pub private_access_key: PathBuf,
pub public_access_key: PathBuf,
pub private_refresh_key: PathBuf,
pub public_refresh_key: PathBuf,
}

impl SecretConfig {
pub fn read_private_access_key(&self) -> Result<String, std::io::Error> {
fs::read_to_string(util::dir::root_dir(&self.private_access_key)?)
fs::read_to_string(util::dir::get_project_root()?.join(&self.private_access_key))
}

pub fn read_public_access_key(&self) -> Result<String, std::io::Error> {
fs::read_to_string(util::dir::root_dir(&self.public_access_key)?)
fs::read_to_string(util::dir::get_project_root()?.join(&self.public_access_key))
}

pub fn read_private_refresh_key(&self) -> Result<String, std::io::Error> {
fs::read_to_string(util::dir::root_dir(&self.private_refresh_key)?)
fs::read_to_string(util::dir::get_project_root()?.join(&self.private_refresh_key))
}

pub fn read_public_refresh_key(&self) -> Result<String, std::io::Error> {
fs::read_to_string(util::dir::root_dir(&self.public_refresh_key)?)
fs::read_to_string(util::dir::get_project_root()?.join(&self.public_refresh_key))
}
}

Expand Down
13 changes: 7 additions & 6 deletions src/constant/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ use utoipa::OpenApi;

use crate::{
client::{email::EmailClient, http::HttpClient, redis::RedisClient, ClientBuilder},
configure::template::TemplateEngine,
configure::{env::get_env_source, get_static_dir, template::TemplateEngine},
handler::openapi::ApiDoc,
util,
};

pub const ENV_PREFIX: &str = "APP";
pub const CODE_LEN: usize = 5;
pub const CLIENT_TIMEOUT: Duration = Duration::from_secs(120);
pub const EXPIRE_SESSION_CODE_SECS: Duration = Duration::from_secs(2000);
Expand All @@ -26,11 +26,11 @@ pub const AUTHORIZATION: &str = "Authorization";
pub const BEARER: &str = "Bearer";
pub const APP_DOMAIN: &str = "rustfulapi.com";
pub const APP_EMAIL_ADDR: &str = "[email protected]";
pub static IMAGES_PATH: Lazy<PathBuf> = Lazy::new(|| util::dir::root_dir("static/images").unwrap());
pub static IMAGES_PATH: Lazy<PathBuf> = Lazy::new(|| get_static_dir().unwrap().join("images"));
pub static APP_IMAGE: Lazy<PathBuf> =
Lazy::new(|| util::dir::root_dir("static/images/logo.jpg").unwrap());
Lazy::new(|| get_static_dir().unwrap().join("images/logo.jpg"));
pub static CONFIG: Lazy<crate::configure::AppConfig> =
Lazy::new(|| crate::configure::AppConfig::read().unwrap());
Lazy::new(|| crate::configure::AppConfig::read(get_env_source(ENV_PREFIX)).unwrap());
pub static HTTP: Lazy<reqwest::Client> =
Lazy::new(|| HttpClient::build_from_config(&CONFIG).unwrap());
pub static REDIS: Lazy<RedisClient> =
Expand All @@ -57,8 +57,9 @@ pub static ACCESS_TOKEN_DECODE_KEY: Lazy<DecodingKey> = Lazy::new(|| {
});
pub static API_DOC: Lazy<utoipa::openapi::OpenApi> = Lazy::new(ApiDoc::openapi);
pub static TEMPLATE_ENGIN: Lazy<TemplateEngine> = Lazy::new(|| {
let path = util::dir::root_dir("static/template/**/*")
let path = get_static_dir()
.unwrap()
.join("template/**/*")
.into_os_string()
.into_string()
.unwrap();
Expand Down
41 changes: 33 additions & 8 deletions src/util/dir.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,34 @@
use std::path::Path;

pub fn root_dir<P: AsRef<Path> + ?Sized>(path: &P) -> std::io::Result<std::path::PathBuf> {
Ok(
project_root::get_project_root()
.or_else(|_| std::env::current_dir())?
.join(path),
)
use std::path::PathBuf;

pub fn get_project_root() -> std::io::Result<PathBuf> {
if let Some(root) = get_cargo_project_root()? {
Ok(root)
} else {
Ok(std::env::current_dir()?)
}
}

pub fn get_cargo_project_root() -> std::io::Result<Option<PathBuf>> {
let current_path = std::env::current_dir()?;

for ancestor in current_path.ancestors() {
for dir in std::fs::read_dir(ancestor)? {
let dir = dir?;
if dir.file_name() == *"Cargo.lock" {
return Ok(Some(ancestor.to_path_buf()));
}
}
}
Ok(None)
}

#[cfg(test)]
mod tests {
use super::get_cargo_project_root;

#[test]
fn test_get_cargo_project_root() {
let root = get_cargo_project_root().unwrap().unwrap();
assert_eq!(root.file_name().unwrap().to_str().unwrap(), "rustfulapi");
}
}
8 changes: 0 additions & 8 deletions src/util/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,6 @@ pub async fn store_file<P: AsRef<Path>>(file_path: &P, content: &[u8]) -> AppRes
Ok(())
}

pub fn root_dir<P: AsRef<Path> + ?Sized>(path: &P) -> std::io::Result<std::path::PathBuf> {
Ok(
project_root::get_project_root()
.or_else(|_| std::env::current_dir())?
.join(path),
)
}

#[cfg(test)]
mod tests {
use std::path::PathBuf;
Expand Down
File renamed without changes.
5 changes: 3 additions & 2 deletions tests/api/context/app.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use once_cell::sync::Lazy;
use rustfulapi::{
client::database::{drop_database, migrate_database, setup_new_database, DatabaseClient},
configure::AppConfig,
configure::{env::get_env_source, AppConfig},
constant::ENV_PREFIX,
error::AppResult,
server::{self, state::AppState, worker::MessengerTask},
};
Expand All @@ -25,7 +26,7 @@ pub struct AppTestContext {
impl AsyncTestContext for AppTestContext {
async fn setup() -> Self {
Lazy::force(&INIT_SUBSCRIBER);
let mut config = AppConfig::read().unwrap();
let mut config = AppConfig::read(get_env_source(ENV_PREFIX)).unwrap();
let default_db = setup_new_database(&mut config).await.unwrap();
let server = server::AppServer::new(config).await.unwrap();
migrate_database(&server.state.db).await.unwrap();
Expand Down

0 comments on commit 9ddb294

Please sign in to comment.