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 r2d2;
|
||||
extern crate r2d2_diesel;
|
||||
extern crate serde;
|
||||
extern crate serde_json;
|
||||
extern crate serde_urlencoded;
|
||||
extern crate slug;
|
||||
|
|
|
@ -9,14 +9,16 @@ use site::Layout;
|
|||
use state::State;
|
||||
use web::{Resource, ResponseFuture};
|
||||
|
||||
use super::pagination::Pagination;
|
||||
|
||||
pub struct ChangesResource {
|
||||
state: State,
|
||||
before: Option<i32>,
|
||||
}
|
||||
|
||||
impl ChangesResource {
|
||||
pub fn new(state: State, before: Option<i32>) -> Self {
|
||||
Self { state, before }
|
||||
pub fn new(state: State, pagination: Pagination<i32>) -> Self {
|
||||
Self { state, before: match pagination { Pagination::Before(x) => Some(x), _ => None } }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
pub mod pagination;
|
||||
|
||||
mod article_redirect_resource;
|
||||
mod article_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::str::Utf8Error;
|
||||
|
||||
use futures::{Future, finished, failed};
|
||||
use futures::{Future, finished, failed, done};
|
||||
use futures::future::FutureResult;
|
||||
use percent_encoding::percent_decode;
|
||||
use serde_urlencoded;
|
||||
use slug::slugify;
|
||||
|
||||
use resources::*;
|
||||
|
@ -84,17 +83,12 @@ impl WikiLookup {
|
|||
("_assets", Some(asset)) =>
|
||||
Box::new(asset_lookup(asset)),
|
||||
("_changes", None) => {
|
||||
#[derive(Deserialize)]
|
||||
struct Query {
|
||||
before: Option<i32>,
|
||||
}
|
||||
|
||||
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)))
|
||||
Box::new(done(
|
||||
pagination::from_str(query.unwrap_or("")).map_err(Into::into)
|
||||
.and_then(|pagination| Ok(Some(
|
||||
Box::new(ChangesResource::new(self.state.clone(), pagination)) as BoxResource
|
||||
)))
|
||||
))
|
||||
},
|
||||
("_new", None) =>
|
||||
Box::new(finished(Some(Box::new(NewArticleResource::new(self.state.clone(), None)) as BoxResource))),
|
||||
|
|
Loading…
Reference in a new issue