v0.5.3-pre.005-fix010

This commit is contained in:
2026-08-14 14:40:36 +02:00
parent b6583bd9fb
commit 734a27f2ca
59 changed files with 4337 additions and 747 deletions

View File

@@ -1,5 +1,5 @@
// file: ks-store/src/contracts/pagination.rs
// version: 4
// version: 5
//! Backend-neutral pagination contracts for repository operations.
@@ -103,6 +103,33 @@ impl<T> crate::PageSlice<T> {
}
}
/// One bounded page with a refreshed total row count for the same filter.
#[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize)]
pub struct CountedPageSlice<T> {
/// Rows returned for this page.
pub rows: std::vec::Vec<T>,
/// Opaque cursor for the next page when additional rows exist.
pub next_cursor: std::option::Option<std::string::String>,
/// Total number of rows matching the filter at query time.
pub total_rows: u64,
}
impl<T> crate::CountedPageSlice<T> {
/// Builds one counted page.
pub fn new(
rows: std::vec::Vec<T>,
next_cursor: std::option::Option<std::string::String>,
total_rows: u64,
) -> Self {
return Self { rows, next_cursor, total_rows };
}
/// Returns true when this page has no continuation cursor.
pub fn is_last_page(&self) -> bool {
return self.next_cursor.is_none();
}
}
#[cfg(test)]
mod tests {
#[test]
@@ -135,4 +162,15 @@ mod tests {
let page = crate::PageSlice::new(vec![1_u32], std::option::Option::None);
assert!(page.is_last_page());
}
#[test]
fn counted_page_preserves_total_rows_and_cursor_state() {
let page = crate::CountedPageSlice::new(
vec![1_u32, 2_u32],
std::option::Option::Some("cursor".to_string()),
501,
);
assert_eq!(page.total_rows, 501);
assert!(!page.is_last_page());
}
}