Propage database connections; dispatch requests
This commit is contained in:
parent
9ce7ff7fe1
commit
139a5b51b6
3 changed files with 70 additions and 11 deletions
|
@ -11,6 +11,7 @@ use std::net::SocketAddr;
|
||||||
mod db;
|
mod db;
|
||||||
mod schema;
|
mod schema;
|
||||||
mod site;
|
mod site;
|
||||||
|
mod state;
|
||||||
|
|
||||||
fn args<'a>() -> clap::ArgMatches<'a> {
|
fn args<'a>() -> clap::ArgMatches<'a> {
|
||||||
use clap::{App, Arg};
|
use clap::{App, Arg};
|
||||||
|
@ -35,19 +36,17 @@ fn args<'a>() -> clap::ArgMatches<'a> {
|
||||||
fn core_main() -> Result<(), Box<std::error::Error>> {
|
fn core_main() -> Result<(), Box<std::error::Error>> {
|
||||||
let args = args();
|
let args = args();
|
||||||
|
|
||||||
let db_file = args.value_of("DATABASE").expect("Guaranteed by clap");
|
let db_file = args.value_of("DATABASE").expect("Guaranteed by clap").to_owned();
|
||||||
let bind_host = "127.0.0.1".parse().unwrap();
|
let bind_host = "127.0.0.1".parse().unwrap();
|
||||||
let bind_port = args.value_of("port")
|
let bind_port = args.value_of("port")
|
||||||
.map(|p| p.parse().expect("Guaranteed by validator"))
|
.map(|p| p.parse().expect("Guaranteed by validator"))
|
||||||
.unwrap_or(8080);
|
.unwrap_or(8080);
|
||||||
|
|
||||||
let _db_connection = db::connect_database(db_file, true);
|
|
||||||
|
|
||||||
let server =
|
let server =
|
||||||
hyper::server::Http::new()
|
hyper::server::Http::new()
|
||||||
.bind(
|
.bind(
|
||||||
&SocketAddr::new(bind_host, bind_port),
|
&SocketAddr::new(bind_host, bind_port),
|
||||||
|| Ok(site::Site {})
|
move || Ok(site::Site::new(state::State::new(db::connect_database(&db_file, true))))
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
server.run()?;
|
server.run()?;
|
||||||
|
|
47
src/site.rs
47
src/site.rs
|
@ -3,12 +3,20 @@ use hyper;
|
||||||
use hyper::header::ContentType;
|
use hyper::header::ContentType;
|
||||||
use hyper::mime;
|
use hyper::mime;
|
||||||
use hyper::server::*;
|
use hyper::server::*;
|
||||||
|
use state::State;
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref TEXT_HTML: mime::Mime = "text/html;charset=utf-8".parse().unwrap();
|
static ref TEXT_HTML: mime::Mime = "text/html;charset=utf-8".parse().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Site {
|
pub struct Site {
|
||||||
|
state: State
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Site {
|
||||||
|
pub fn new(state: State) -> Site {
|
||||||
|
Site { state }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Service for Site {
|
impl Service for Site {
|
||||||
|
@ -17,12 +25,47 @@ impl Service for Site {
|
||||||
type Error = hyper::Error;
|
type Error = hyper::Error;
|
||||||
type Future = futures::BoxFuture<Response, Self::Error>;
|
type Future = futures::BoxFuture<Response, Self::Error>;
|
||||||
|
|
||||||
fn call(&self, _req: Request) -> Self::Future {
|
fn call(&self, req: Request) -> Self::Future {
|
||||||
|
println!("{} {}", req.method(), req.path());
|
||||||
|
|
||||||
|
let path = req.path();
|
||||||
|
|
||||||
|
if path.starts_with("/_") {
|
||||||
futures::finished(
|
futures::finished(
|
||||||
Response::new()
|
Response::new()
|
||||||
.with_header(ContentType(TEXT_HTML.clone()))
|
.with_header(ContentType(TEXT_HTML.clone()))
|
||||||
.with_body(format!("WOOOOOOOOOOT!"))
|
.with_body(format!("Page not found"))
|
||||||
|
.with_status(hyper::StatusCode::NotFound)
|
||||||
|
).boxed()
|
||||||
|
} else {
|
||||||
|
assert!(path.starts_with("/"));
|
||||||
|
match self.state.find_article_by_slug(&path[1..]) {
|
||||||
|
Ok(Some(article)) => {
|
||||||
|
futures::finished(
|
||||||
|
Response::new()
|
||||||
|
.with_header(ContentType(TEXT_HTML.clone()))
|
||||||
|
.with_body(format!("Article found."))
|
||||||
.with_status(hyper::StatusCode::Ok)
|
.with_status(hyper::StatusCode::Ok)
|
||||||
).boxed()
|
).boxed()
|
||||||
|
},
|
||||||
|
Ok(None) => {
|
||||||
|
futures::finished(
|
||||||
|
Response::new()
|
||||||
|
.with_header(ContentType(TEXT_HTML.clone()))
|
||||||
|
.with_body(format!("Article not found."))
|
||||||
|
.with_status(hyper::StatusCode::NotFound)
|
||||||
|
).boxed()
|
||||||
|
},
|
||||||
|
Err(err) => {
|
||||||
|
eprintln!("Error while servicing request {} {}:\n{:#?}", req.method(), req.path(), err);
|
||||||
|
futures::finished(
|
||||||
|
Response::new()
|
||||||
|
.with_header(ContentType(TEXT_HTML.clone()))
|
||||||
|
.with_body(format!("Internal server error"))
|
||||||
|
.with_status(hyper::StatusCode::InternalServerError)
|
||||||
|
).boxed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
17
src/state.rs
Normal file
17
src/state.rs
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
use std;
|
||||||
|
|
||||||
|
use diesel::sqlite::SqliteConnection;
|
||||||
|
|
||||||
|
pub struct State {
|
||||||
|
db_connection: SqliteConnection
|
||||||
|
}
|
||||||
|
|
||||||
|
impl State {
|
||||||
|
pub fn new(db_connection: SqliteConnection) -> State {
|
||||||
|
State { db_connection }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn find_article_by_slug(&self, slug: &str) -> Result<Option<()>, Box<std::error::Error>> {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue