init ƸӜƷ

This commit is contained in:
mtrx 2025-05-04 04:02:09 +02:00
commit 30969e1cee
9 changed files with 1870 additions and 0 deletions

93
src/config.rs Normal file
View 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
View file

@ -0,0 +1,2 @@
LL_REQUIRED_VARIABLE=foo
LL_OPTIONAL_VARIABLE=bar

56
src/config/eval/tests.rs Normal file
View 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
View file

@ -0,0 +1,3 @@
mod sqlite;
let CONN = sqlite::connection::establish_connection();

22
src/main.rs Normal file
View 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
}