Refactor handling of pagination query arguments
This commit is contained in:
parent
a42010a1f8
commit
0dacad5a3e
5 changed files with 43 additions and 15 deletions
|
@ -16,6 +16,7 @@ extern crate percent_encoding;
|
||||||
extern crate pulldown_cmark;
|
extern crate pulldown_cmark;
|
||||||
extern crate r2d2;
|
extern crate r2d2;
|
||||||
extern crate r2d2_diesel;
|
extern crate r2d2_diesel;
|
||||||
|
extern crate serde;
|
||||||
extern crate serde_json;
|
extern crate serde_json;
|
||||||
extern crate serde_urlencoded;
|
extern crate serde_urlencoded;
|
||||||
extern crate slug;
|
extern crate slug;
|
||||||
|
|
|
@ -9,14 +9,16 @@ use site::Layout;
|
||||||
use state::State;
|
use state::State;
|
||||||
use web::{Resource, ResponseFuture};
|
use web::{Resource, ResponseFuture};
|
||||||
|
|
||||||
|
use super::pagination::Pagination;
|
||||||
|
|
||||||
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, before: Option<i32>) -> Self {
|
pub fn new(state: State, pagination: Pagination<i32>) -> Self {
|
||||||
Self { state, before }
|
Self { state, before: match pagination { Pagination::Before(x) => Some(x), _ => None } }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
pub mod pagination;
|
||||||
|
|
||||||
mod article_redirect_resource;
|
mod article_redirect_resource;
|
||||||
mod article_resource;
|
mod article_resource;
|
||||||
mod changes_resource;
|
mod changes_resource;
|
||||||
|
|
29
src/resources/pagination.rs
Normal file
29
src/resources/pagination.rs
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
use serde;
|
||||||
|
use serde_urlencoded;
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct PaginationStruct<T> {
|
||||||
|
after: Option<T>,
|
||||||
|
before: Option<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum Pagination<T> {
|
||||||
|
After(T),
|
||||||
|
Before(T),
|
||||||
|
None,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> PaginationStruct<T> {
|
||||||
|
fn into_enum(self) -> Pagination<T> {
|
||||||
|
match (self.after, self.before) {
|
||||||
|
(Some(x), _) => Pagination::After(x),
|
||||||
|
(None, Some(x)) => Pagination::Before(x),
|
||||||
|
_ => Pagination::None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_str<'a, T: serde::Deserialize<'a>>(s: &'a str) -> Result<Pagination<T>, serde::de::value::Error> {
|
||||||
|
let pagination: PaginationStruct<T> = serde_urlencoded::from_str(s)?;
|
||||||
|
Ok(pagination.into_enum())
|
||||||
|
}
|
|
@ -2,10 +2,9 @@ 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};
|
use futures::{Future, finished, failed, done};
|
||||||
use futures::future::FutureResult;
|
use futures::future::FutureResult;
|
||||||
use percent_encoding::percent_decode;
|
use percent_encoding::percent_decode;
|
||||||
use serde_urlencoded;
|
|
||||||
use slug::slugify;
|
use slug::slugify;
|
||||||
|
|
||||||
use resources::*;
|
use resources::*;
|
||||||
|
@ -84,17 +83,12 @@ impl WikiLookup {
|
||||||
("_assets", Some(asset)) =>
|
("_assets", Some(asset)) =>
|
||||||
Box::new(asset_lookup(asset)),
|
Box::new(asset_lookup(asset)),
|
||||||
("_changes", None) => {
|
("_changes", None) => {
|
||||||
#[derive(Deserialize)]
|
Box::new(done(
|
||||||
struct Query {
|
pagination::from_str(query.unwrap_or("")).map_err(Into::into)
|
||||||
before: Option<i32>,
|
.and_then(|pagination| Ok(Some(
|
||||||
}
|
Box::new(ChangesResource::new(self.state.clone(), pagination)) as BoxResource
|
||||||
|
)))
|
||||||
let query: Query = match serde_urlencoded::from_str(query.unwrap_or("")) {
|
))
|
||||||
Ok(x) => x,
|
|
||||||
Err(x) => return Box::new(failed(x.into())),
|
|
||||||
};
|
|
||||||
|
|
||||||
Box::new(finished(Some(Box::new(ChangesResource::new(self.state.clone(), query.before)) as BoxResource)))
|
|
||||||
},
|
},
|
||||||
("_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))),
|
||||||
|
|
Loading…
Reference in a new issue