Propage database connections; dispatch requests

This commit is contained in:
Johannes Hoff 2017-08-20 21:59:16 +02:00
parent 9ce7ff7fe1
commit 139a5b51b6
3 changed files with 70 additions and 11 deletions

View file

@ -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()?;

View file

@ -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
View 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)
}
}