pub const DEFAULT_LIMIT: usize = 100;
pub const DEFAULT_OFFSET: usize = 0;
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct Paging {
pub current: String,
pub offset: usize,
pub limit: usize,
pub total: usize,
pub first: String,
pub prev: String,
pub next: String,
pub last: String,
}
pub fn get_response_paging_info(
limit: Option<usize>,
offset: Option<usize>,
link: &str,
query_count: usize,
) -> Paging {
let limit = limit.unwrap_or(DEFAULT_LIMIT);
let offset = offset.unwrap_or(DEFAULT_OFFSET);
let base_link = {
if !link.contains('?') {
format!("{}?limit={}&", link, limit)
} else {
format!("{}limit={}&", link, limit)
}
};
let current_link = format!("{}offset={}", base_link, offset);
let first_link = format!("{}offset=0", base_link);
let previous_offset = if offset > limit { offset - limit } else { 0 };
let previous_link = format!("{}offset={}", base_link, previous_offset);
let last_offset = if query_count > 0 {
((query_count - 1) / limit) * limit
} else {
0
};
let last_link = format!("{}offset={}", base_link, last_offset);
let next_offset = if offset + limit > last_offset {
last_offset
} else {
offset + limit
};
let next_link = format!("{}offset={}", base_link, next_offset);
Paging {
current: current_link,
offset,
limit,
total: query_count,
first: first_link,
prev: previous_link,
next: next_link,
last: last_link,
}
}
#[cfg(test)]
mod tests {
use super::*;
const TEST_LINK: &str = "/api/test?";
#[test]
fn test_default_paging_response() {
let test_paging_response = get_response_paging_info(None, None, TEST_LINK, 1000);
let generated_paging_response =
create_test_paging_response(DEFAULT_OFFSET, DEFAULT_LIMIT, 100, 0, 900);
assert_eq!(test_paging_response, generated_paging_response);
}
#[test]
fn test_50offset_paging_response() {
let test_paging_response = get_response_paging_info(None, Some(50), TEST_LINK, 1000);
let generated_paging_response = create_test_paging_response(50, DEFAULT_LIMIT, 150, 0, 900);
assert_eq!(test_paging_response, generated_paging_response);
}
#[test]
fn test_550offset_paging_response() {
let test_paging_response = get_response_paging_info(None, Some(550), TEST_LINK, 1000);
let generated_paging_response =
create_test_paging_response(550, DEFAULT_LIMIT, 650, 450, 900);
assert_eq!(test_paging_response, generated_paging_response);
}
#[test]
fn test_950offset_paging_response() {
let test_paging_response = get_response_paging_info(None, Some(950), TEST_LINK, 1000);
let generated_paging_response =
create_test_paging_response(950, DEFAULT_LIMIT, 900, 850, 900);
assert_eq!(test_paging_response, generated_paging_response);
}
#[test]
fn test_50limit_paging_response() {
let test_paging_response = get_response_paging_info(Some(50), None, TEST_LINK, 1000);
let generated_paging_response = create_test_paging_response(DEFAULT_OFFSET, 50, 50, 0, 950);
assert_eq!(test_paging_response, generated_paging_response);
}
#[test]
fn test_50limit_150offset_paging_response() {
let test_paging_response = get_response_paging_info(Some(50), Some(150), TEST_LINK, 1000);
let generated_paging_response = create_test_paging_response(150, 50, 200, 100, 950);
assert_eq!(test_paging_response, generated_paging_response);
}
fn create_test_paging_response(
offset: usize,
limit: usize,
next_offset: usize,
previous_offset: usize,
last_offset: usize,
) -> Paging {
let base_link = format!("{}limit={}&", TEST_LINK, limit);
let current_link = format!("{}offset={}", base_link, offset);
let first_link = format!("{}offset=0", base_link);
let next_link = format!("{}offset={}", base_link, next_offset);
let previous_link = format!("{}offset={}", base_link, previous_offset);
let last_link = format!("{}offset={}", base_link, last_offset);
Paging {
current: current_link,
offset,
limit,
total: 1000,
first: first_link,
prev: previous_link,
next: next_link,
last: last_link,
}
}
}