Make State-functons return Future-s

This commit is contained in:
Magnus Hoff 2017-09-08 15:58:15 +02:00
parent 50b9ebf59e
commit b3e7552c16
2 changed files with 19 additions and 20 deletions

View file

@ -77,27 +77,24 @@ struct WikiLookup {
impl Lookup for WikiLookup { impl Lookup for WikiLookup {
type Resource = ArticleResource; type Resource = ArticleResource;
type Error = Box<::std::error::Error + Send + Sync>; type Error = Box<::std::error::Error + Send + Sync>;
type Future = futures::future::FutureResult<Option<Self::Resource>, Self::Error>; type Future = futures::BoxFuture<Option<Self::Resource>, Self::Error>;
fn lookup(&self, path: &str, _query: Option<&str>, _fragment: Option<&str>) -> Self::Future { fn lookup(&self, path: &str, _query: Option<&str>, _fragment: Option<&str>) -> Self::Future {
assert!(path.starts_with("/")); assert!(path.starts_with("/"));
if path.starts_with("/_") { if path.starts_with("/_") {
// Reserved namespace // Reserved namespace
return futures::finished(None); return futures::finished(None).boxed();
} }
let slug = &path[1..]; let slug = &path[1..];
if let Ok(article_id) = slug.parse() { if let Ok(article_id) = slug.parse() {
match self.state.get_article_revision_by_id(article_id) { let state = self.state.clone();
Ok(Some(article)) => { self.state.get_article_revision_by_id(article_id)
futures::finished(Some(ArticleResource::new(self.state.clone(), article))) .and_then(|x| Ok(x.map(move |article| ArticleResource::new(state, article))))
}, .boxed()
Ok(None) => futures::finished(None),
Err(err) => futures::failed(err),
}
} else { } else {
futures::finished(None) futures::finished(None).boxed()
} }
} }
} }

View file

@ -3,7 +3,7 @@ use std;
use diesel; use diesel;
use diesel::sqlite::SqliteConnection; use diesel::sqlite::SqliteConnection;
use diesel::prelude::*; use diesel::prelude::*;
use futures::{self, Future, IntoFuture}; use futures::{Future, IntoFuture, BoxFuture};
use r2d2::Pool; use r2d2::Pool;
use r2d2_diesel::ConnectionManager; use r2d2_diesel::ConnectionManager;
@ -21,18 +21,20 @@ impl State {
State { connection_pool } State { connection_pool }
} }
pub fn get_article_revision_by_id(&self, article_id: i32) -> Result<Option<models::ArticleRevision>, Error> { pub fn get_article_revision_by_id(&self, article_id: i32) -> BoxFuture<Option<models::ArticleRevision>, Error> {
use schema::article_revisions; (|| -> Result<_, _> {
use schema::article_revisions;
Ok(article_revisions::table Ok(article_revisions::table
.filter(article_revisions::article_id.eq(article_id)) .filter(article_revisions::article_id.eq(article_id))
.order(article_revisions::revision.desc()) .order(article_revisions::revision.desc())
.limit(1) .limit(1)
.load::<models::ArticleRevision>(&*self.connection_pool.get()?)? .load::<models::ArticleRevision>(&*self.connection_pool.get()?)?
.pop()) .pop())
}()).into_future().boxed()
} }
pub fn update_article(&self, article_id: i32, base_revision: i32, body: String) -> futures::BoxFuture<models::ArticleRevision, Error> { pub fn update_article(&self, article_id: i32, base_revision: i32, body: String) -> BoxFuture<models::ArticleRevision, Error> {
self.connection_pool.get().into_future() self.connection_pool.get().into_future()
.map_err(Into::into) .map_err(Into::into)
.and_then(move |conn| { .and_then(move |conn| {