init ƸӜƷ
This commit is contained in:
commit
30969e1cee
9 changed files with 1870 additions and 0 deletions
93
src/config.rs
Normal file
93
src/config.rs
Normal file
|
@ -0,0 +1,93 @@
|
|||
use dotenvy::dotenv;
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
pub const ENV_PREFIX: &str = "LL_";
|
||||
|
||||
pub struct Config {
|
||||
pub submit_token: String,
|
||||
pub root_path: String,
|
||||
pub username: String,
|
||||
pub bind_port: String,
|
||||
pub accounts: Accounts,
|
||||
}
|
||||
|
||||
pub struct Accounts {
|
||||
pub email: Option<String>,
|
||||
pub github: Option<String>,
|
||||
pub twitter: Option<String>,
|
||||
pub mastodon: Option<String>,
|
||||
pub discord: Option<String>,
|
||||
pub reddit: Option<String>,
|
||||
}
|
||||
|
||||
mod eval {
|
||||
mod tests;
|
||||
use super::ENV_PREFIX;
|
||||
|
||||
// return config value or panic if not set
|
||||
pub fn required(variable_name: &str) -> String {
|
||||
let key = format!("{ENV_PREFIX}{variable_name}");
|
||||
|
||||
match std::env::var(key) {
|
||||
Ok(value) => {
|
||||
println!("{}: {}", variable_name, value);
|
||||
return value;
|
||||
}
|
||||
Err(_) => {
|
||||
panic!("Environment variable '{}' not set!", variable_name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return optional value
|
||||
pub fn optional(variable_name: &str, default_value: Option<&str>) -> Option<String> {
|
||||
let key = format!("{ENV_PREFIX}{variable_name}");
|
||||
match std::env::var(key) {
|
||||
Ok(value) => {
|
||||
println!("{}: {}", variable_name, value);
|
||||
return Some(value);
|
||||
}
|
||||
Err(_) => match default_value {
|
||||
Some(val) => {
|
||||
println!("Environment variable '{variable_name}' not set. Using default value: {val}.");
|
||||
return Some(String::from(val));
|
||||
}
|
||||
None => {
|
||||
println!("Environment variable '{variable_name}' not set. No default, leaving this empty.");
|
||||
None
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn load_config() -> Config {
|
||||
use eval::*;
|
||||
|
||||
match dotenv() {
|
||||
Ok(_) => {
|
||||
println!(".env exists, loading environment variables.")
|
||||
}
|
||||
Err(_) => {
|
||||
println!(".env does not exist, possibly the docker image is run which requires to set environment variables manually.")
|
||||
}
|
||||
}
|
||||
|
||||
Config {
|
||||
submit_token: required("SUBMIT_TOKEN"),
|
||||
root_path: optional("ROOT_PATH", Some("./content")).unwrap(),
|
||||
username: required("USERNAME"),
|
||||
bind_port: optional("BIND_PORT", Some("8000")).unwrap(),
|
||||
accounts: Accounts {
|
||||
email: optional("EMAIL", None),
|
||||
github: optional("GITHUB_ACCOUNT", None),
|
||||
discord: optional("DISCORD_ACCOUNT", None),
|
||||
twitter: optional("TWITTER_ACCOUNT", None),
|
||||
mastodon: optional("MASTODON_ACCOUNT", None),
|
||||
reddit: optional("REDDIT_ACCOUNT", None),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub static CONFIG: Lazy<Config> = Lazy::new(|| load_config());
|
2
src/config/eval/test.env
Normal file
2
src/config/eval/test.env
Normal file
|
@ -0,0 +1,2 @@
|
|||
LL_REQUIRED_VARIABLE=foo
|
||||
LL_OPTIONAL_VARIABLE=bar
|
56
src/config/eval/tests.rs
Normal file
56
src/config/eval/tests.rs
Normal file
|
@ -0,0 +1,56 @@
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use dotenvy::from_path;
|
||||
use std::path::Path;
|
||||
|
||||
use crate::config::eval::{optional, required};
|
||||
|
||||
fn load_test_config() {
|
||||
from_path(Path::new("./src/config/eval/test.env"));
|
||||
}
|
||||
|
||||
// workaround until rust supports setup and teardown tags
|
||||
// https://github.com/rust-lang/rust/issues/117668
|
||||
fn setup() {
|
||||
load_test_config();
|
||||
}
|
||||
|
||||
// content if required var is missing
|
||||
#[test]
|
||||
fn test_required_existing_and_set() {
|
||||
setup();
|
||||
assert!(required("REQUIRED_VARIABLE") == "foo");
|
||||
}
|
||||
|
||||
// panic if required var is missing
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_required_missing() {
|
||||
setup();
|
||||
required("REQUIRED_VARIABLE_MISSING");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_optional_variable_set() {
|
||||
setup();
|
||||
assert!(optional("OPTIONAL_VARIABLE", None).unwrap() == "bar");
|
||||
}
|
||||
|
||||
// optional variable is missing, that's ok. None should be set if default was specified as None.
|
||||
#[test]
|
||||
fn test_optional_missing_no_default_is_none() {
|
||||
setup();
|
||||
assert!(optional("OPTIONAL_VARIABLE_MISSING", None).is_none());
|
||||
}
|
||||
|
||||
// optional variable is missing, that's ok. We need to make sure a default was set if specified.
|
||||
#[test]
|
||||
fn test_optional_missing_with_default_is_default() {
|
||||
setup();
|
||||
let default_value = "some default";
|
||||
assert!(
|
||||
optional("OPTIONAL_VARIABLE_MISSING", Some(default_value)).unwrap()
|
||||
== default_value
|
||||
);
|
||||
}
|
||||
}
|
3
src/db.rs
Normal file
3
src/db.rs
Normal file
|
@ -0,0 +1,3 @@
|
|||
mod sqlite;
|
||||
|
||||
let CONN = sqlite::connection::establish_connection();
|
22
src/main.rs
Normal file
22
src/main.rs
Normal file
|
@ -0,0 +1,22 @@
|
|||
mod config;
|
||||
|
||||
// extern crate diesel;
|
||||
// extern crate chrono;
|
||||
// extern crate serde_derive;
|
||||
|
||||
use actix_web::{middleware::Logger, App, HttpServer};
|
||||
use config::CONFIG;
|
||||
use env_logger::Env;
|
||||
|
||||
#[actix_web::main]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
HttpServer::new(move || {
|
||||
env_logger::Builder::from_env(Env::default().default_filter_or("debug"));
|
||||
|
||||
App::new()
|
||||
.wrap(Logger::new("%a %r %t"))
|
||||
})
|
||||
.bind(format!("0.0.0.0:{}", CONFIG.bind_port))?
|
||||
.run()
|
||||
.await
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue