1
use actix_web::{web, App, HttpServer};
2
use log::info;
3
use ngi0review::{app, data::Data};
4
use std::path::PathBuf;
5

            
6
const HELP: &str = "\
7
USAGE:
8
  ngi0review [OPTIONS]
9
FLAGS:
10
  -h, --help Prints help information
11
OPTIONS:
12
  --data DIR     The directory with the data and configuration files.
13
  --bind ADDRESS The interface address to bind to. (default: 127.0.0.1)
14
  --port PORT    The port to bind to. (default 8085)
15
";
16

            
17
struct Arguments {
18
    data_dir: Option<PathBuf>,
19
    bind: String,
20
    port: u16,
21
}
22

            
23
fn parse_path(s: &std::ffi::OsStr) -> Result<std::path::PathBuf, &'static str> {
24
    Ok(s.into())
25
}
26

            
27
fn parse_args() -> Result<Arguments, pico_args::Error> {
28
    let mut pargs = pico_args::Arguments::from_env();
29
    if pargs.contains(["-h", "--help"]) {
30
        print!("{}", HELP);
31
        std::process::exit(0);
32
    }
33
    let args = Arguments {
34
        data_dir: pargs.opt_value_from_os_str("--data", parse_path)?,
35
        bind: pargs
36
            .opt_value_from_str("--bind")?
37
            .unwrap_or_else(|| "127.0.0.1".into()),
38
        port: pargs.opt_value_from_str("--port")?.unwrap_or(8085),
39
    };
40
    Ok(args)
41
}
42

            
43
#[actix_web::main]
44
async fn main() -> Result<(), Box<dyn std::error::Error>> {
45
    env_logger::init_from_env(env_logger::Env::new().default_filter_or("debug"));
46
    let args = parse_args()?;
47
    info!("Starting server on http://{}:{}", args.bind, args.port);
48
    let data = web::Data::new(Data::new(
49
        args.data_dir.unwrap_or_else(|| PathBuf::from("data")),
50
    )?);
51
    HttpServer::new(move || {
52
        let mut cors = actix_cors::Cors::default()
53
            .supports_credentials()
54
            .allow_any_method()
55
            .allow_any_header();
56
        if data.config().allowed_origins.is_empty() {
57
            cors = cors.allow_any_origin();
58
        } else {
59
            for allowed_origin in &data.config().allowed_origins {
60
                cors = cors.allowed_origin(allowed_origin);
61
            }
62
        }
63
        app!(data.clone(), cors)
64
    })
65
    .bind((args.bind, args.port))?
66
    .run()
67
    .await?;
68
    Ok(())
69
}