actix_web_pagination/
parse.rs1use super::pagination::Pagination;
2use super::pagination_config::PaginationConfig;
3
4use actix_web::dev;
5use actix_web::web;
6use actix_web::FromRequest;
7use actix_web::HttpRequest;
8use futures_util::future;
9
10impl FromRequest for Pagination {
11 type Error = actix_web::Error;
12
13 type Future = future::Ready<actix_web::Result<Self>>;
14
15 type Config = ();
16
17 fn from_request(req: &HttpRequest, _payload: &mut dev::Payload) -> Self::Future {
18 future::ready(Pagination::parse(req))
19 }
20}
21
22impl Pagination {
23 pub(crate) fn parse(req: &HttpRequest) -> actix_web::Result<Pagination> {
24 let config = req
25 .app_data_resolved()
26 .unwrap_or(&PaginationConfig::DEFAULT);
27
28 let mut it = config.pagination();
29 form_urlencoded::parse(req.query_string().as_bytes()).for_each(|(k, v)| match k {
30 _ if k == config.page_name => it.page = config.parse_page(&v) as _,
31 _ if k == config.per_page_name => it.per_page = config.parse_per_page(&v) as _,
32 _ => {}
33 });
34
35 Ok(it)
36 }
37}
38
39trait HttpRequestExt {
40 fn app_data_resolved<T: 'static>(&self) -> Option<&T>;
41}
42
43impl HttpRequestExt for HttpRequest {
44 fn app_data_resolved<T: 'static>(&self) -> Option<&T> {
45 self.app_data()
46 .or_else(|| self.app_data::<web::Data<T>>().map(|it| it.as_ref()))
47 }
48}