//! Copyright (c) 2022-2026 GitDataAi All rights reserved. use crate::pb::{PageInfo, Pagination}; /// Simple offset-based pagination over an in-memory slice. /// The `page_token` is a decimal string encoding the start offset. pub fn paginate(items: &[T], pagination: Option<&Pagination>) -> (Vec, PageInfo) { let page_size = pagination .map(|p| p.page_size as usize) .unwrap_or(items.len().max(1)) .max(1); let start_offset = pagination .and_then(|p| { if p.page_token.is_empty() { None } else { p.page_token.parse::().ok() } }) .unwrap_or(0) .min(items.len()); let end = start_offset.saturating_add(page_size).min(items.len()); let has_next = end < items.len(); let next_page_token = if has_next { end.to_string() } else { String::new() }; ( items[start_offset..end].to_vec(), PageInfo { next_page_token, has_next_page: has_next, total_count: items.len() as u64, }, ) } /// Apply sort direction. Ascending = no-op (preserves order). /// Descending reverses the slice. pub fn apply_sort(items: &mut [T], sort_direction: i32) { if sort_direction == crate::pb::SortDirection::Desc as i32 { items.reverse(); } }