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::{self, Future};
|
||||||
use futures::future::finished;
|
use futures::future::{done, finished};
|
||||||
use hyper;
|
use hyper;
|
||||||
use hyper::header::ContentType;
|
use hyper::header::ContentType;
|
||||||
use hyper::server::*;
|
use hyper::server::*;
|
||||||
|
@ -17,39 +17,61 @@ const PAGE_SIZE: i32 = 30;
|
||||||
|
|
||||||
type BoxResource = Box<Resource + Sync + Send>;
|
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 {
|
pub struct ChangesResource {
|
||||||
state: State,
|
state: State,
|
||||||
before: Option<i32>,
|
before: Option<i32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ChangesResource {
|
impl ChangesResource {
|
||||||
pub fn new(state: State, pagination: Pagination<i32>) -> Box<Future<Item=BoxResource, Error=::web::Error>> {
|
pub fn new(state: State, before: Option<i32>) -> Self {
|
||||||
match pagination {
|
Self { state, before }
|
||||||
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)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ mod temporary_redirect_resource;
|
||||||
|
|
||||||
pub use self::article_redirect_resource::ArticleRedirectResource;
|
pub use self::article_redirect_resource::ArticleRedirectResource;
|
||||||
pub use self::article_resource::ArticleResource;
|
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::new_article_resource::NewArticleResource;
|
||||||
pub use self::sitemap_resource::SitemapResource;
|
pub use self::sitemap_resource::SitemapResource;
|
||||||
pub use self::temporary_redirect_resource::TemporaryRedirectResource;
|
pub use self::temporary_redirect_resource::TemporaryRedirectResource;
|
||||||
|
|
|
@ -2,7 +2,7 @@ use std::borrow::Cow;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::str::Utf8Error;
|
use std::str::Utf8Error;
|
||||||
|
|
||||||
use futures::{Future, finished, failed, done};
|
use futures::{Future, finished, failed};
|
||||||
use futures::future::FutureResult;
|
use futures::future::FutureResult;
|
||||||
use percent_encoding::percent_decode;
|
use percent_encoding::percent_decode;
|
||||||
use slug::slugify;
|
use slug::slugify;
|
||||||
|
@ -40,7 +40,8 @@ lazy_static! {
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct WikiLookup {
|
pub struct WikiLookup {
|
||||||
state: State
|
state: State,
|
||||||
|
changes_lookup: ChangesLookup,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn split_one(path: &str) -> Result<(Cow<str>, Option<&str>), Utf8Error> {
|
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 {
|
impl WikiLookup {
|
||||||
pub fn new(state: State) -> 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 {
|
fn reserved_lookup(&self, path: &str, query: Option<&str>) -> <Self as Lookup>::Future {
|
||||||
|
@ -82,14 +85,8 @@ impl WikiLookup {
|
||||||
match (head.as_ref(), tail) {
|
match (head.as_ref(), tail) {
|
||||||
("_assets", Some(asset)) =>
|
("_assets", Some(asset)) =>
|
||||||
Box::new(asset_lookup(asset)),
|
Box::new(asset_lookup(asset)),
|
||||||
("_changes", None) => {
|
("_changes", None) =>
|
||||||
let state = self.state.clone();
|
Box::new(ChangesLookup::new(self.state.clone()).lookup(query)),
|
||||||
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)))
|
|
||||||
)
|
|
||||||
},
|
|
||||||
("_new", None) =>
|
("_new", None) =>
|
||||||
Box::new(finished(Some(Box::new(NewArticleResource::new(self.state.clone(), None)) as BoxResource))),
|
Box::new(finished(Some(Box::new(NewArticleResource::new(self.state.clone(), None)) as BoxResource))),
|
||||||
("_sitemap", None) =>
|
("_sitemap", None) =>
|
||||||
|
|
Loading…
Reference in a new issue