feat(core): implement Git repository operations with gRPC services
- Add advertise_refs functionality for Git protocol communication - Implement archive service with TAR/ZIP format support and streaming - Create blame service for Git file annotation with line tracking - Add branch management including create, delete, rename and compare operations - Implement merge checking with conflict detection and fast-forward handling - Add cherry-pick functionality for applying commits between branches - Integrate gix library for Git repository operations and object handling - Add comprehensive test suite covering all Git operations - Implement proper error handling and repository validation - Add pagination support for large result sets - Create protobuf definitions for all Git operations and data structures - Add build system for gRPC code generation and dependency management
This commit is contained in:
+46
@@ -0,0 +1,46 @@
|
||||
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<T: Clone>(items: &[T], pagination: Option<&Pagination>) -> (Vec<T>, 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::<usize>().ok()
|
||||
}
|
||||
})
|
||||
.unwrap_or(0)
|
||||
.min(items.len());
|
||||
|
||||
let end = std::cmp::min(start_offset + page_size, 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<T>(items: &mut [T], sort_direction: i32) {
|
||||
if sort_direction == crate::pb::SortDirection::Desc as i32 {
|
||||
items.reverse();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user