82 lines
2.3 KiB
Rust
82 lines
2.3 KiB
Rust
#![allow(dead_code)]
|
|
use std::net::SocketAddr;
|
|
use std::path::PathBuf;
|
|
|
|
use actix_files::Files;
|
|
use actix_web::{
|
|
http::{Method, StatusCode},
|
|
middleware::{self, ErrorHandlers},
|
|
web, App, HttpServer,
|
|
};
|
|
use clap::Parser;
|
|
use handlebars::Handlebars;
|
|
|
|
mod errors;
|
|
mod main_pages;
|
|
mod template_utils;
|
|
|
|
use errors::generic_error;
|
|
use main_pages::{mail_post, template};
|
|
|
|
#[derive(Parser, Debug, Clone)]
|
|
struct Config {
|
|
#[clap(long, value_parser)]
|
|
/// The directory from which to serve static content and
|
|
/// handlebars templates
|
|
template_directory: PathBuf,
|
|
#[clap(long, default_value = "127.0.0.1:8000", value_parser)]
|
|
/// The address on which to listen
|
|
address: SocketAddr,
|
|
#[clap(long, action)]
|
|
/// Whether to start the server in dev mode; this enables some
|
|
/// nice handlebars features that are not intended for production
|
|
dev_mode: bool,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
struct SharedData<'a> {
|
|
handlebars: Handlebars<'a>,
|
|
config: Config,
|
|
}
|
|
|
|
#[actix_web::main]
|
|
async fn main() -> std::io::Result<()> {
|
|
let mut config = Config::parse();
|
|
config.template_directory = config.template_directory.canonicalize()?;
|
|
|
|
env_logger::init();
|
|
|
|
let mut handlebars = Handlebars::new();
|
|
handlebars
|
|
.register_templates_directory(".html", config.template_directory.clone())
|
|
.expect("templates should compile correctly");
|
|
handlebars.set_dev_mode(config.dev_mode);
|
|
|
|
let shared_data = web::Data::new(SharedData {
|
|
handlebars,
|
|
config: config.clone(),
|
|
});
|
|
|
|
HttpServer::new(move || {
|
|
App::new()
|
|
.wrap(middleware::NormalizePath::trim())
|
|
// TODO(tlater): When actix-web 4.3 releases, this can be improved a
|
|
// lot because of this PR:
|
|
//
|
|
// https://github.com/actix/actix-web/pull/2784
|
|
.wrap(
|
|
ErrorHandlers::new()
|
|
.handler(StatusCode::NOT_FOUND, generic_error)
|
|
.handler(StatusCode::INTERNAL_SERVER_ERROR, generic_error),
|
|
)
|
|
.app_data(shared_data.clone())
|
|
.service(template)
|
|
.service(mail_post)
|
|
.service(Files::new("/", &config.template_directory))
|
|
.default_service(web::route().method(Method::GET))
|
|
})
|
|
.bind(config.address)?
|
|
.run()
|
|
.await
|
|
}
|