Skip to content

Commit c079a3c

Browse files
committed
[FEATURE] Pagination logic implemented.
1 parent 5dfaf65 commit c079a3c

File tree

5 files changed

+87
-4
lines changed

5 files changed

+87
-4
lines changed

src/infrastructure/controller.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
use axum::{body::Body, extract::Path, http::{Response, StatusCode}, response::IntoResponse, routing::{get, post}, Json, Router};
1+
use axum::{body::Body, extract::{Path, Query}, http::{Response, StatusCode}, response::IntoResponse, routing::{get, post}, Json, Router};
22

33
use rust_db_manager_core::commons::configuration::configuration::Configuration;
44

55
use crate::{commons::exception::api_exception::ApiException, domain::builder_db_service::BuilderDBService};
66

7-
use super::dto::db_service::{dto_db_service::DTODBService, dto_db_service_lite::DTODBServiceLite};
7+
use super::{dto::{db_service::{dto_db_service::DTODBService, dto_db_service_lite::DTODBServiceLite, dto_paginated_collection::DTOPaginatedCollection}, dto_query_pagination::DTOQueryPagination}, pagination::Pagination};
88

99
pub struct Controller{
1010
}
@@ -18,10 +18,11 @@ impl Controller {
1818
.route("/:service/status", get(Controller::status))
1919
}
2020

21-
async fn services() -> (StatusCode, Json<Vec<DTODBServiceLite>>) {
21+
async fn services(Query(params): Query<DTOQueryPagination>) -> (StatusCode, Json<DTOPaginatedCollection<DTODBServiceLite>>) {
2222
let services = Configuration::find_services();
2323
let dto = DTODBServiceLite::from_vec(services);
24-
(StatusCode::ACCEPTED, Json(dto))
24+
let result = Pagination::paginate(params, dto);
25+
(StatusCode::ACCEPTED, Json(result))
2526
}
2627

2728
async fn insert_service(Json(dto): Json<DTODBService>) -> Result<(StatusCode, String), impl IntoResponse> {
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
use serde::{Deserialize, Serialize};
2+
3+
#[derive(Clone, Serialize, Deserialize)]
4+
pub struct DTOPaginatedCollection<T> {
5+
pub total: usize,
6+
pub previous: usize,
7+
pub next: usize,
8+
pub services: Vec<T>,
9+
}
10+
11+
impl <T> DTOPaginatedCollection<T> {
12+
13+
pub fn new(total: usize, previous: usize, next: usize, services: Vec<T>) -> DTOPaginatedCollection<T> {
14+
DTOPaginatedCollection {total, previous, next, services}
15+
}
16+
17+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
use serde::Deserialize;
2+
3+
#[derive(Debug, Deserialize)]
4+
pub struct DTOQueryPagination {
5+
pub offset: usize,
6+
pub limit: usize,
7+
}

src/infrastructure/pagination.rs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
use super::dto::{db_service::dto_paginated_collection::DTOPaginatedCollection, dto_query_pagination::DTOQueryPagination};
2+
3+
pub struct Pagination {}
4+
5+
impl Pagination {
6+
7+
pub fn paginate<T: Clone>(params: DTOQueryPagination, collection: Vec<T>) -> DTOPaginatedCollection<T> {
8+
let size = collection.len();
9+
let offset = params.offset;
10+
let limit = params.limit;
11+
12+
if offset >= size {
13+
let previous = Pagination::calculate_previous(size, offset, limit);
14+
return DTOPaginatedCollection::new(size, previous, size, Vec::new());
15+
}
16+
17+
if size == 0 || limit == 0 {
18+
return DTOPaginatedCollection::new(size, offset, offset, Vec::new());
19+
}
20+
21+
let mut limit_fixed = limit;
22+
if offset + limit >= size {
23+
limit_fixed = size - offset;
24+
}
25+
26+
let cursor = offset + limit_fixed;
27+
28+
let next = Pagination::calculate_next(size, cursor, limit);
29+
let previous = Pagination::calculate_previous(size, cursor, limit);
30+
31+
let slice = collection[offset..=cursor-1].to_vec();
32+
33+
return DTOPaginatedCollection::new(size, previous, next, slice);
34+
}
35+
36+
fn calculate_next(size: usize, cursor: usize, limit: usize) -> usize {
37+
let next = cursor + limit;
38+
if next >= size {
39+
return size;
40+
}
41+
return next;
42+
}
43+
44+
fn calculate_previous(size: usize, cursor: usize, limit: usize) -> usize {
45+
if cursor.checked_sub(limit).is_none() {
46+
return 0;
47+
}
48+
let previous = cursor - limit;
49+
if previous > size {
50+
return Pagination::calculate_previous(size, size, limit);
51+
}
52+
return previous;
53+
}
54+
55+
}

src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,12 @@ pub mod infrastructure {
1212
pub mod db_service {
1313
pub mod dto_db_connection_data;
1414
pub mod dto_db_service;
15+
pub mod dto_paginated_collection;
1516
pub mod dto_db_service_lite;
1617
}
18+
pub mod dto_query_pagination;
1719
}
1820
pub mod controller;
21+
pub mod pagination;
1922
pub mod utils;
2023
}

0 commit comments

Comments
 (0)