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 {
type Resource = ArticleResource;
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 {
assert!(path.starts_with("/"));
if path.starts_with("/_") {
// Reserved namespace
return futures::finished(None);
return futures::finished(None).boxed();
}
let slug = &path[1..];
if let Ok(article_id) = slug.parse() {
match self.state.get_article_revision_by_id(article_id) {
Ok(Some(article)) => {
futures::finished(Some(ArticleResource::new(self.state.clone(), article)))
},
Ok(None) => futures::finished(None),
Err(err) => futures::failed(err),
}
let state = self.state.clone();
self.state.get_article_revision_by_id(article_id)
.and_then(|x| Ok(x.map(move |article| ArticleResource::new(state, article))))
.boxed()
} else {
futures::finished(None)
futures::finished(None).boxed()
}
}
}

View file

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