use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Page<T> {
pub items: Vec<T>,
pub page_info: PageInfo,
}
impl<T> Page<T> {
pub fn is_empty(&self) -> bool {
self.items.is_empty()
}
pub fn len(&self) -> usize {
self.items.len()
}
pub fn has_next(&self) -> bool {
self.page_info.has_next
}
pub fn next_cursor(&self) -> Option<&str> {
self.page_info.next_cursor.as_deref()
}
}
impl<T> Default for Page<T> {
fn default() -> Self {
Self {
items: Vec::new(),
page_info: PageInfo::default(),
}
}
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct PageInfo {
pub has_next: bool,
pub next_cursor: Option<String>,
pub total_count: Option<u64>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum SortOrder {
#[default]
Ascending,
Descending,
}
impl SortOrder {
pub fn is_ascending(&self) -> bool {
matches!(self, SortOrder::Ascending)
}
pub fn is_descending(&self) -> bool {
matches!(self, SortOrder::Descending)
}
pub fn as_str(&self) -> &'static str {
match self {
SortOrder::Ascending => "asc",
SortOrder::Descending => "desc",
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_page_empty() {
let page: Page<String> = Page::default();
assert!(page.is_empty());
assert_eq!(page.len(), 0);
assert!(!page.has_next());
assert!(page.next_cursor().is_none());
}
#[test]
fn test_page_with_items() {
let page = Page {
items: vec!["item1".to_string(), "item2".to_string()],
page_info: PageInfo {
has_next: true,
next_cursor: Some("cursor_abc".to_string()),
total_count: Some(10),
},
};
assert!(!page.is_empty());
assert_eq!(page.len(), 2);
assert!(page.has_next());
assert_eq!(page.next_cursor(), Some("cursor_abc"));
}
#[test]
fn test_sort_order() {
assert!(SortOrder::Ascending.is_ascending());
assert!(!SortOrder::Ascending.is_descending());
assert!(!SortOrder::Descending.is_ascending());
assert!(SortOrder::Descending.is_descending());
assert_eq!(SortOrder::default(), SortOrder::Ascending);
}
#[test]
fn test_sort_order_as_str() {
assert_eq!(SortOrder::Ascending.as_str(), "asc");
assert_eq!(SortOrder::Descending.as_str(), "desc");
}
}