surwiki/src/main.rs

123 lines
3.5 KiB
Rust
Raw Normal View History

#![recursion_limit="128"] // for diesel's infer_schema!
2017-08-20 23:17:16 +03:00
#[macro_use] extern crate bart_derive;
2017-08-19 23:48:51 +03:00
#[macro_use] extern crate diesel;
#[macro_use] extern crate diesel_codegen;
2017-10-18 17:33:21 +03:00
#[macro_use] extern crate hyper;
2017-08-20 21:46:08 +03:00
#[macro_use] extern crate lazy_static;
2017-11-02 17:19:23 +03:00
#[macro_use] extern crate maplit;
#[macro_use] extern crate serde_derive;
#[macro_use] extern crate static_resource_derive;
2017-08-19 23:48:51 +03:00
2017-08-20 23:17:16 +03:00
extern crate chrono;
2017-08-19 23:48:51 +03:00
extern crate clap;
extern crate diff;
2017-08-20 21:46:08 +03:00
extern crate futures;
2017-09-08 17:21:24 +03:00
extern crate futures_cpupool;
2017-10-02 00:24:16 +03:00
extern crate percent_encoding;
2017-09-01 17:34:24 +03:00
extern crate pulldown_cmark;
extern crate r2d2;
extern crate r2d2_diesel;
extern crate serde;
2017-09-05 18:07:57 +03:00
extern crate serde_json;
extern crate serde_urlencoded;
extern crate slug;
extern crate titlecase;
2017-08-20 21:24:10 +03:00
2017-10-30 16:59:39 +03:00
use std::net::{IpAddr, SocketAddr};
2017-08-19 23:48:51 +03:00
2017-09-15 18:28:23 +03:00
mod assets;
2017-08-19 23:48:51 +03:00
mod db;
mod mimes;
2017-08-20 23:17:16 +03:00
mod models;
mod rendering;
2017-10-13 16:21:23 +03:00
mod resources;
2017-08-19 23:48:51 +03:00
mod schema;
2017-08-20 21:24:10 +03:00
mod site;
mod state;
mod web;
2017-09-15 18:28:23 +03:00
mod wiki_lookup;
2017-08-19 23:48:51 +03:00
const DATABASE: &str = "DATABASE";
const TRUST_IDENTITY: &str = "trust-identity";
2017-10-30 16:59:39 +03:00
const ADDRESS: &str = "address";
const PORT: &str = "port";
2017-08-19 23:48:51 +03:00
fn args<'a>() -> clap::ArgMatches<'a> {
use clap::{App, Arg};
App::new(env!("CARGO_PKG_NAME"))
.version(env!("CARGO_PKG_VERSION"))
.about(env!("CARGO_PKG_DESCRIPTION"))
.arg(Arg::with_name(DATABASE)
2017-08-19 23:48:51 +03:00
.help("Sets the database file to use")
2017-08-20 21:24:10 +03:00
.required(true))
.arg(Arg::with_name(PORT)
2017-11-01 13:51:58 +03:00
.help("Sets the listening port")
2017-08-20 21:24:10 +03:00
.short("p")
.long(PORT)
2017-11-01 13:51:58 +03:00
.default_value("8080")
2017-08-20 21:40:08 +03:00
.validator(|x| match x.parse::<u16>() {
Ok(_) => Ok(()),
2017-10-30 16:59:39 +03:00
Err(_) => Err("Must be an integer in the range [0, 65535]".into())
})
.takes_value(true))
.arg(Arg::with_name(ADDRESS)
2017-11-01 13:51:58 +03:00
.help("Sets the IP address to bind to")
2017-10-30 16:59:39 +03:00
.short("a")
.long(ADDRESS)
2017-11-01 13:51:58 +03:00
.default_value("127.0.0.1")
2017-10-30 16:59:39 +03:00
.validator(|x| match x.parse::<IpAddr>() {
Ok(_) => Ok(()),
Err(_) => Err("Must be a valid IP address".into())
2017-08-20 21:40:08 +03:00
})
2017-08-20 21:24:10 +03:00
.takes_value(true))
.arg(Arg::with_name(TRUST_IDENTITY)
.help("Trust the value in the X-Identity header to be an \
authenticated username. This only makes sense when Sausagewiki \
runs behind a reverse proxy which sets this header.")
.long(TRUST_IDENTITY))
2017-08-19 23:48:51 +03:00
.get_matches()
}
2017-08-20 21:40:08 +03:00
fn core_main() -> Result<(), Box<std::error::Error>> {
let args = args();
2017-11-01 13:51:58 +03:00
const CLAP: &str = "Guaranteed by clap";
const VALIDATOR: &str = "Guaranteed by clap validator";
let db_file = args.value_of(DATABASE).expect(CLAP).to_owned();
let bind_host = args.value_of(ADDRESS).expect(CLAP).parse().expect(VALIDATOR);
let bind_port = args.value_of(PORT).expect(CLAP).parse().expect(VALIDATOR);
2017-08-20 21:40:08 +03:00
let trust_identity = args.is_present(TRUST_IDENTITY);
let db_pool = db::create_pool(db_file)?;
2017-09-10 13:29:33 +03:00
let cpu_pool = futures_cpupool::CpuPool::new_num_cpus();
let state = state::State::new(db_pool, cpu_pool);
let lookup = wiki_lookup::WikiLookup::new(state, trust_identity);
2017-08-20 21:24:10 +03:00
let server =
hyper::server::Http::new()
.bind(
&SocketAddr::new(bind_host, bind_port),
move || Ok(site::Site::new(lookup.clone(), trust_identity))
2017-08-20 21:24:10 +03:00
)?;
2017-08-22 17:40:18 +03:00
println!("Listening on http://{}", server.local_addr().unwrap());
2017-08-20 21:24:10 +03:00
server.run()?;
Ok(())
}
2017-08-19 23:48:51 +03:00
fn main() {
2017-08-20 21:40:08 +03:00
match core_main() {
Ok(()) => (),
Err(err) => {
eprintln!("{:#?}", err);
std::process::exit(1)
}
}
2017-08-19 23:48:51 +03:00
}