Factor out pagination resolver from ChangesResource and call it ChangesLookup
This commit is contained in:
parent
b3ffcb916b
commit
0f1e1f65ed
3 changed files with 59 additions and 40 deletions
|
@ -1,5 +1,5 @@
|
|||
use futures::{self, Future};
|
||||
use futures::future::finished;
|
||||
use futures::future::{done, finished};
|
||||
use hyper;
|
||||
use hyper::header::ContentType;
|
||||
use hyper::server::*;
|
||||
|
@ -17,39 +17,61 @@ const PAGE_SIZE: i32 = 30;
|
|||
|
||||
type BoxResource = Box<Resource + Sync + Send>;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ChangesLookup {
|
||||
state: State,
|
||||
}
|
||||
|
||||
impl ChangesLookup {
|
||||
pub fn new(state: State) -> ChangesLookup {
|
||||
Self { state }
|
||||
}
|
||||
|
||||
pub fn lookup(&self, query: Option<&str>) -> Box<Future<Item=Option<BoxResource>, Error=::web::Error>> {
|
||||
use super::pagination;
|
||||
|
||||
let state = self.state.clone();
|
||||
|
||||
Box::new(
|
||||
done(pagination::from_str(query.unwrap_or("")).map_err(Into::into))
|
||||
.and_then(move |pagination| match pagination {
|
||||
Pagination::After(x) => Box::new(
|
||||
state.query_article_revision_stubs(move |query| {
|
||||
use diesel::prelude::*;
|
||||
use schema::article_revisions::dsl::*;
|
||||
|
||||
query
|
||||
.limit(PAGE_SIZE as i64 + 1)
|
||||
.filter(sequence_number.gt(x))
|
||||
.order(sequence_number.asc())
|
||||
}).and_then(|mut data| {
|
||||
let extra_element = if data.len() > PAGE_SIZE as usize {
|
||||
data.pop()
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
Ok(Some(match extra_element {
|
||||
Some(x) => Box::new(TemporaryRedirectResource::new(format!("?before={}", x.sequence_number))) as BoxResource,
|
||||
None => Box::new(TemporaryRedirectResource::new(format!("_changes"))) as BoxResource,
|
||||
}))
|
||||
})
|
||||
) as Box<Future<Item=Option<BoxResource>, Error=::web::Error>>,
|
||||
Pagination::Before(x) => Box::new(finished(Some(Box::new(ChangesResource::new(state, Some(x))) as BoxResource))),
|
||||
Pagination::None => Box::new(finished(Some(Box::new(ChangesResource::new(state, None)) as BoxResource))),
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ChangesResource {
|
||||
state: State,
|
||||
before: Option<i32>,
|
||||
}
|
||||
|
||||
impl ChangesResource {
|
||||
pub fn new(state: State, pagination: Pagination<i32>) -> Box<Future<Item=BoxResource, Error=::web::Error>> {
|
||||
match pagination {
|
||||
Pagination::After(x) => Box::new(
|
||||
state.query_article_revision_stubs(move |query| {
|
||||
use diesel::prelude::*;
|
||||
use schema::article_revisions::dsl::*;
|
||||
|
||||
query
|
||||
.limit(PAGE_SIZE as i64 + 1)
|
||||
.filter(sequence_number.gt(x))
|
||||
.order(sequence_number.asc())
|
||||
}).and_then(|mut data| {
|
||||
let extra_element = if data.len() > PAGE_SIZE as usize {
|
||||
data.pop()
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
Ok(match extra_element {
|
||||
Some(x) => Box::new(TemporaryRedirectResource::new(format!("?before={}", x.sequence_number))) as BoxResource,
|
||||
None => Box::new(TemporaryRedirectResource::new(format!("_changes"))) as BoxResource,
|
||||
})
|
||||
})
|
||||
),
|
||||
Pagination::Before(x) => Box::new(finished(Box::new(Self { state, before: Some(x) }) as BoxResource)),
|
||||
Pagination::None => Box::new(finished(Box::new(Self { state, before: None }) as BoxResource)),
|
||||
}
|
||||
pub fn new(state: State, before: Option<i32>) -> Self {
|
||||
Self { state, before }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ mod temporary_redirect_resource;
|
|||
|
||||
pub use self::article_redirect_resource::ArticleRedirectResource;
|
||||
pub use self::article_resource::ArticleResource;
|
||||
pub use self::changes_resource::ChangesResource;
|
||||
pub use self::changes_resource::{ChangesLookup, ChangesResource};
|
||||
pub use self::new_article_resource::NewArticleResource;
|
||||
pub use self::sitemap_resource::SitemapResource;
|
||||
pub use self::temporary_redirect_resource::TemporaryRedirectResource;
|
||||
|
|
|
@ -2,7 +2,7 @@ use std::borrow::Cow;
|
|||
use std::collections::HashMap;
|
||||
use std::str::Utf8Error;
|
||||
|
||||
use futures::{Future, finished, failed, done};
|
||||
use futures::{Future, finished, failed};
|
||||
use futures::future::FutureResult;
|
||||
use percent_encoding::percent_decode;
|
||||
use slug::slugify;
|
||||
|
@ -40,7 +40,8 @@ lazy_static! {
|
|||
|
||||
#[derive(Clone)]
|
||||
pub struct WikiLookup {
|
||||
state: State
|
||||
state: State,
|
||||
changes_lookup: ChangesLookup,
|
||||
}
|
||||
|
||||
fn split_one(path: &str) -> Result<(Cow<str>, Option<&str>), Utf8Error> {
|
||||
|
@ -70,7 +71,9 @@ fn asset_lookup(path: &str) -> FutureResult<Option<BoxResource>, Box<::std::erro
|
|||
|
||||
impl WikiLookup {
|
||||
pub fn new(state: State) -> WikiLookup {
|
||||
WikiLookup { state }
|
||||
let changes_lookup = ChangesLookup::new(state.clone());
|
||||
|
||||
WikiLookup { state, changes_lookup }
|
||||
}
|
||||
|
||||
fn reserved_lookup(&self, path: &str, query: Option<&str>) -> <Self as Lookup>::Future {
|
||||
|
@ -82,14 +85,8 @@ impl WikiLookup {
|
|||
match (head.as_ref(), tail) {
|
||||
("_assets", Some(asset)) =>
|
||||
Box::new(asset_lookup(asset)),
|
||||
("_changes", None) => {
|
||||
let state = self.state.clone();
|
||||
Box::new(
|
||||
done(pagination::from_str(query.unwrap_or("")).map_err(Into::into))
|
||||
.and_then(move |pagination| ChangesResource::new(state, pagination))
|
||||
.and_then(|resource| Ok(Some(resource)))
|
||||
)
|
||||
},
|
||||
("_changes", None) =>
|
||||
Box::new(ChangesLookup::new(self.state.clone()).lookup(query)),
|
||||
("_new", None) =>
|
||||
Box::new(finished(Some(Box::new(NewArticleResource::new(self.state.clone(), None)) as BoxResource))),
|
||||
("_sitemap", None) =>
|
||||
|
|
Loading…
Reference in a new issue