hive-forge: add --since cursor paging to comments and timeline
This commit is contained in:
parent
f6629f0c23
commit
4cf647aa70
3 changed files with 159 additions and 70 deletions
|
|
@ -69,6 +69,56 @@ pub(crate) fn rfc3339(ts: Option<OffsetDateTime>) -> Option<String> {
|
|||
ts.and_then(|t| t.format(&Rfc3339).ok())
|
||||
}
|
||||
|
||||
/// Parse a `--since`/`--before` CLI argument as RFC 3339 — the inverse of
|
||||
/// [`rfc3339`], so a value copied straight from this tool's own output
|
||||
/// (every row prints its `created_at` in this exact shape) round-trips
|
||||
/// without reformatting. A bad value gets a message naming what was
|
||||
/// typed, not a bare parser error.
|
||||
pub(crate) fn parse_rfc3339(s: &str) -> Result<OffsetDateTime> {
|
||||
OffsetDateTime::parse(s, &Rfc3339)
|
||||
.map_err(|e| anyhow::anyhow!("`{s}` isn't a valid RFC 3339 timestamp: {e}"))
|
||||
}
|
||||
|
||||
/// Forgejo's per-page cap, shared by every listing verb that over-fetches
|
||||
/// by one to detect truncation without an exact total (`timeline`'s
|
||||
/// `--limit`, `comments`' `--since`). The API silently clamps a requested
|
||||
/// page size to this value, so it's pinned explicitly rather than left as
|
||||
/// a hidden default downstream math could drift out of sync with.
|
||||
pub(crate) const PAGE_SIZE: u64 = 50;
|
||||
|
||||
/// The highest `--limit` an over-fetch-by-one truncation check
|
||||
/// (`fetch_limit = limit + 1`) can still detect: `PAGE_SIZE - 1`. At
|
||||
/// `limit == PAGE_SIZE` the `+1` request silently clamps to `PAGE_SIZE`
|
||||
/// server-side and the truncation check goes blind exactly when there's
|
||||
/// the most data to miss.
|
||||
pub(crate) const MAX_LIMIT: u64 = PAGE_SIZE - 1;
|
||||
|
||||
/// Cap `requested` at [`MAX_LIMIT`], reporting whether it had to. Pure so
|
||||
/// the boundary math is unit-testable without a network call.
|
||||
pub(crate) fn clamp_limit(requested: u64) -> (u64, bool) {
|
||||
let limit = requested.min(MAX_LIMIT);
|
||||
(limit, limit < requested)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod page_limit_tests {
|
||||
use super::{MAX_LIMIT, PAGE_SIZE, clamp_limit};
|
||||
|
||||
#[test]
|
||||
fn clamp_limit_passes_small_requests_through() {
|
||||
assert_eq!(clamp_limit(10), (10, false));
|
||||
assert_eq!(clamp_limit(MAX_LIMIT), (MAX_LIMIT, false));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn clamp_limit_caps_requests_above_the_boundary() {
|
||||
// Regression: `limit + 1` must never exceed Forgejo's PAGE_SIZE,
|
||||
// or the over-fetch-by-one truncation check goes silently blind.
|
||||
assert_eq!(clamp_limit(PAGE_SIZE), (MAX_LIMIT, true));
|
||||
assert_eq!(clamp_limit(1000), (MAX_LIMIT, true));
|
||||
}
|
||||
}
|
||||
|
||||
/// Issue-vs-PR kind, for the `pr <verb>` / `issue <verb>` sub-command
|
||||
/// validation.
|
||||
#[derive(Clone, Copy)]
|
||||
|
|
|
|||
Loading…
Reference in a new issue