feat: Initialisation des properties.toml + spawn du premier process Actix

This commit is contained in:
max 2024-01-16 00:03:40 +00:00
parent 3d7b5f2c5b
commit 23e7e708e4
10 changed files with 2842 additions and 3 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
/target
.env

View File

@ -10,6 +10,7 @@
"bierner.markdown-mermaid",
"hristian-kohler.path-intellisense",
"helixquar.randomeverything",
"shardulm94.trailing-spaces"
"shardulm94.trailing-spaces",
"tamasfe.even-better-toml"
]
}

2581
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,37 @@
name = "botdiscord"
version = "0.1.0"
edition = "2021"
default-run = "botdiscord"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
serde = "1.0"
uuid = { version = "1.4", features = ["v4", "serde"] }
chrono = { version = "0.4", features = ["serde"] }
utoipa = { version = "4", features = ["actix_extras", "chrono", "uuid"] }
serde_json = "1.0"
tokio-postgres = { version = "0.7", features = [
"with-uuid-1",
"with-chrono-0_4",
"with-serde_json-1",
] }
reqwest = { version = "0.11", features = ["json"] }
deadpool-postgres = { version = "0.11", features = ["serde"] }
openssl = { version = "0.10", features = ["vendored"] }
postgres-openssl = "0.5.0"
toml = "0.8"
actix-web = "4"
actix-cors = "0.6.4"
utoipa-swagger-ui = { version = "4.0.0", features = ["actix-web"] }
regex = "1.10.0"
dotenvy = "0.15.7"
actix = "0.13.1"
serial_test = "2.0.0"
[[bin]]
name = "botdiscord"
path = "src/main.rs"
test = true

View File

@ -28,6 +28,22 @@ components:
value: "dev-che"
- name: "PORT"
value: "5437"
- name: postgres
container:
image: postgres:15
memoryLimit: 2Gi
endpoints:
- name: postgres
targetPort: 5432
env:
- name: POSTGRES_USER
value: "postgres"
- name: POSTGRES_PASSWORD
value: "postgres"
- name: POSTGRES_DB
value: "postgres"
- name: PGDATA
value: /tmp/pgdata
commands:
- id: build
exec:

12
resources/config.toml Normal file
View File

@ -0,0 +1,12 @@
bot_name = "AGAU"
env = "dev-che"
port = 5437
[persistence]
host = "localhost"
port = 5432
user = "postgres"
password = "postgres"
database = "postgres"
tls = false
tls_insecure = false

View File

@ -0,0 +1,12 @@
bot_name = "AGAU_DEV"
env = "test"
port = 5437
[persistence]
host = "localhost"
port = 5433
user = "GB8eE8vh"
password = "1OLlRZo1tnNluvx"
database = "1pNkVsX3FgFeiQdga"
tls = false
tls_insecure = false

167
src/config.rs Normal file
View File

@ -0,0 +1,167 @@
use dotenvy::dotenv;
use serde::Deserialize;
use std::env;
use std::fs::read_to_string;
use std::path::PathBuf;
const PERSISTENCE_HOST: &str = "PERSISTENCE_HOST";
const PERSISTENCE_PORT: &str = "PERSISTENCE_PORT";
const PERSISTENCE_USER: &str = "PERSISTENCE_USER";
const PERSISTENCE_PWD: &str = "PERSISTENCE_PWD";
const PERSISTENCE_DB: &str = "PERSISTENCE_DB";
const PERSISTENCE_TLS: &str = "PERSISTENCE_TLS";
const PERSISTENCE_TLS_INSECURE: &str = "PERSISTENCE_TLS_INSECURE";
const BOT_NAME: &str = "BOT_NAME";
const RUST_ENV: &str = "RUST_ENV";
const PORT: &str = "PORT";
#[derive(Deserialize, Clone)]
pub struct Config {
pub bot_name: String,
pub persistence: PersistenceConfig,
pub env: String,
pub port: u16,
}
#[derive(Deserialize, Clone)]
pub struct PersistenceConfig {
pub host: String,
pub port: Option<u16>,
pub user: String,
pub password: String,
pub database: String,
pub tls: Option<bool>,
pub tls_insecure: Option<bool>,
}
pub fn parse_local_config() -> Config {
let mut d = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
println!(env!("CARGO_MANIFEST_DIR"));
d.push("resources/config.toml");
match dotenv() {
Ok(_) => println!("Loaded .env file"),
Err(err) => println!("No .env file found: {:?}", err),
}
parse_config(d)
}
#[allow(dead_code)]
pub fn parse_test_config() -> Config {
let mut d = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
d.push("resources/test_config.toml");
parse_config(d)
}
pub fn parse_config(path_buf: PathBuf) -> Config {
let config: Config = parse_config_from_file(path_buf);
override_config_with_env_vars(config)
}
fn parse_config_from_file(path_buf: PathBuf) -> Config {
let config_file = path_buf.into_os_string().into_string().unwrap();
toml::from_str(read_to_string(config_file).unwrap().as_str()).unwrap()
}
fn override_config_with_env_vars(config: Config) -> Config {
let pers = config.persistence;
Config {
bot_name: env::var(BOT_NAME).unwrap_or(config.bot_name),
env: env::var(RUST_ENV).unwrap_or(config.env),
port: env::var(PORT)
.unwrap_or(config.port.to_string())
.parse::<u16>()
.unwrap(),
persistence: PersistenceConfig {
host: env::var(PERSISTENCE_HOST).unwrap_or(pers.host),
port: env::var(PERSISTENCE_PORT)
.map(|p| {
p.parse::<u16>()
.expect("Cannot parse the received persistence port")
})
.ok()
.or(pers.port),
user: env::var(PERSISTENCE_USER).unwrap_or(pers.user),
password: env::var(PERSISTENCE_PWD).unwrap_or(pers.password),
database: env::var(PERSISTENCE_DB).unwrap_or(pers.database),
tls: env::var(PERSISTENCE_TLS)
.map(|p| {
p.parse::<bool>()
.expect("Cannot parse the received persistence tls")
})
.ok()
.or(pers.tls),
tls_insecure: env::var(PERSISTENCE_TLS_INSECURE)
.map(|p| {
p.parse::<bool>()
.expect("Cannot parse the received persistence tls")
})
.ok()
.or(pers.tls_insecure),
},
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::config::parse_config;
use serial_test::serial;
use std::env;
use std::path::PathBuf;
#[test]
#[serial(config)]
fn should_parse_a_config() {
let mut d = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
d.push("resources/test_config.toml");
let config = parse_config(d);
let pers = config.persistence;
assert_eq!("localhost", pers.host);
assert_eq!(5433, pers.port.unwrap());
assert_eq!("GB8eE8vh", pers.user);
assert_eq!("1OLlRZo1tnNluvx", pers.password);
assert_eq!("1pNkVsX3FgFeiQdga", pers.database);
assert_eq!(Some(false), pers.tls);
assert_eq!(Some(false), pers.tls_insecure);
}
#[test]
#[serial(config)]
fn should_override_a_parsed_config_with_env_vars() {
env::set_var(PERSISTENCE_HOST, "my_host");
env::set_var(PERSISTENCE_PORT, "1111");
env::set_var(PERSISTENCE_USER, "just_me");
env::set_var(PERSISTENCE_PWD, "what_a_pwd");
env::set_var(PERSISTENCE_DB, "my_db");
env::set_var(PERSISTENCE_TLS, "true");
env::set_var(PERSISTENCE_TLS_INSECURE, "true");
let mut d = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
d.push("resources/test_config.toml");
let config = parse_config(d);
let pers = config.persistence;
assert_eq!("my_host", pers.host);
assert_eq!(1111, pers.port.unwrap());
assert_eq!("just_me", pers.user);
assert_eq!("what_a_pwd", pers.password);
assert_eq!("my_db", pers.database);
assert_eq!(Some(true), pers.tls);
assert_eq!(Some(true), pers.tls_insecure);
// reset env vars
env::remove_var(PERSISTENCE_HOST);
env::remove_var(PERSISTENCE_PORT);
env::remove_var(PERSISTENCE_USER);
env::remove_var(PERSISTENCE_PWD);
env::remove_var(PERSISTENCE_DB);
env::remove_var(PERSISTENCE_TLS);
env::remove_var(PERSISTENCE_TLS_INSECURE);
}
}

1
src/lib.rs Normal file
View File

@ -0,0 +1 @@
pub mod config;

View File

@ -1,3 +1,21 @@
fn main() {
println!("Hello, world!");
use actix_cors::Cors;
use actix_web::{App, HttpServer};
use botdiscord::config::parse_local_config;
#[actix_web::main] // or #[tokio::main]
async fn main() -> std::io::Result<()> {
let config = parse_local_config();
let port = config.port;
HttpServer::new(|| {
let cors = Cors::default()
.allow_any_header()
.allow_any_method()
.allow_any_origin();
App::new().wrap(cors)
})
.bind(("0.0.0.0", port))?
.run()
.await?;
Ok(())
}