~vpzom/hitide

1806a15bf8500dc2d891f61a1df19ff42f033d36 — Colin Reeder 26 days ago ba83ed4
Support new config loading method (#154)
4 files changed, 128 insertions(+), 7 deletions(-)

M Cargo.lock
M Cargo.toml
A src/config.rs
M src/main.rs
M Cargo.lock => Cargo.lock +55 -0
@@ 25,6 25,12 @@ dependencies = [
]

[[package]]
name = "arrayvec"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"

[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 91,6 97,18 @@ dependencies = [
]

[[package]]
name = "config"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b1b9d958c2b1368a663f05538fc1b5975adce1e19f435acceae987aceeeb369"
dependencies = [
 "lazy_static",
 "nom",
 "rust-ini",
 "serde",
]

[[package]]
name = "core-foundation"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 413,6 431,7 @@ version = "0.8.0-pre"
dependencies = [
 "ammonia",
 "chrono",
 "config",
 "env_logger",
 "fallible-iterator",
 "fluent",


@@ 607,6 626,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"

[[package]]
name = "lexical-core"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe"
dependencies = [
 "arrayvec",
 "bitflags",
 "cfg-if 1.0.0",
 "ryu",
 "static_assertions",
]

[[package]]
name = "libc"
version = "0.2.81"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 766,6 798,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"

[[package]]
name = "nom"
version = "5.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af"
dependencies = [
 "lexical-core",
 "memchr",
 "version_check",
]

[[package]]
name = "num-integer"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 1138,6 1181,12 @@ dependencies = [
]

[[package]]
name = "rust-ini"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e52c148ef37f8c375d49d5a73aa70713125b7f19095948a923f80afdeb22ec2"

[[package]]
name = "ryu"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 1252,6 1301,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"

[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"

[[package]]
name = "string_cache"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"

M Cargo.toml => Cargo.toml +1 -0
@@ 35,3 35,4 @@ multer = "1.2.2"
fluent = "0.13.1"
log = "0.4"
env_logger = "0.8"
config = { version = "0.11.0", default-features = false, features = ["ini"] }

A src/config.rs => src/config.rs +66 -0
@@ 0,0 1,66 @@
use serde_derive::Deserialize;
use std::collections::HashMap;

fn default_port() -> u16 {
    4333
}

#[derive(Deserialize)]
pub struct Config {
    pub backend_host: String,

    #[serde(default = "default_port")]
    pub port: u16,
}

impl Config {
    pub fn load() -> Result<Self, config::ConfigError> {
        let mut src = config::Config::new()
            .with_merged(config::Environment::new())?
            .with_merged(config::Environment::with_prefix("HITIDE"))?;

        {
            let mut args = std::env::args();
            while let Some(arg) = args.next() {
                if arg == "-c" {
                    let path = args.next().expect("Missing parameter for config argument");
                    src.merge(SpecificFile { path: path.into() })?;
                }
            }
        }

        src.try_into()
    }
}

#[derive(Debug, Clone)]
struct SpecificFile {
    path: std::path::PathBuf,
}

impl config::Source for SpecificFile {
    fn clone_into_box(&self) -> Box<dyn config::Source + Send + Sync> {
        Box::new(self.clone())
    }

    fn collect(&self) -> Result<HashMap<String, config::Value>, config::ConfigError> {
        let uri = self.path.to_string_lossy().into_owned();

        let content = match std::fs::read_to_string(&self.path) {
            Ok(content) => content,
            Err(cause) => {
                return Err(config::ConfigError::FileParse {
                    uri: Some(uri),
                    cause: Box::new(cause),
                })
            }
        };

        config::FileFormat::Ini
            .parse(Some(&uri), &content)
            .map_err(|cause| config::ConfigError::FileParse {
                uri: Some(uri),
                cause,
            })
    }
}

M src/main.rs => src/main.rs +6 -7
@@ 8,10 8,13 @@ use std::sync::Arc;
use trout::hyper::RoutingFailureExtHyper;

mod components;
mod config;
mod resp_types;
mod routes;
mod util;

use self::config::Config;

#[derive(Deserialize, PartialEq, Clone, Copy)]
#[serde(rename_all = "snake_case")]
pub enum SortType {


@@ 185,20 188,16 @@ pub fn get_lang_for_req(req: &hyper::Request<hyper::Body>) -> Translator {
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    env_logger::init();
    let backend_host = std::env::var("BACKEND_HOST").expect("Missing BACKEND_HOST");

    let port = match std::env::var("PORT") {
        Ok(port_str) => port_str.parse().expect("Failed to parse port"),
        _ => 4333,
    };
    let config = Config::load().expect("Failed to load config");

    let routes = Arc::new(routes::route_root());
    let context = Arc::new(RouteContext {
        backend_host,
        backend_host: config.backend_host,
        http_client: hyper::Client::builder().build(hyper_tls::HttpsConnector::new()),
    });

    let server = hyper::Server::bind(&(std::net::Ipv6Addr::UNSPECIFIED, port).into()).serve(
    let server = hyper::Server::bind(&(std::net::Ipv6Addr::UNSPECIFIED, config.port).into()).serve(
        hyper::service::make_service_fn(|_| {
            let routes = routes.clone();
            let context = context.clone();