hive-forge: timeline --since no longer errors on an empty window
This commit is contained in:
parent
780df10d9d
commit
7a3e7af6b8
1 changed files with 28 additions and 11 deletions
|
|
@ -25,13 +25,14 @@
|
|||
//! what `forgejo-api` actually returns), so unlike the old `--limit`-only
|
||||
//! shape this is now an exact count, not a boolean "more" flag.
|
||||
|
||||
use anyhow::Result;
|
||||
use anyhow::{Context, Result};
|
||||
use clap::Args as ClapArgs;
|
||||
use forgejo_api::structs::{IssueGetCommentsAndTimelineQuery, TimelineComment};
|
||||
use serde_json::{Value, json};
|
||||
use time::format_description::well_known::Rfc3339;
|
||||
|
||||
use crate::client::{Client, index};
|
||||
use crate::verbs::{MAX_LIMIT, PAGE_SIZE, clamp_limit, parse_rfc3339, print_json};
|
||||
use crate::verbs::{MAX_LIMIT, NullableVec, PAGE_SIZE, clamp_limit, parse_rfc3339, print_json};
|
||||
|
||||
#[derive(ClapArgs)]
|
||||
pub struct Args {
|
||||
|
|
@ -246,6 +247,20 @@ fn fetch_tail(
|
|||
/// `comments.rs`'s `fetch_since` does: ask for `limit + 1`, and a full
|
||||
/// extra row means there's more. Returns `(events, more)`, `more` a
|
||||
/// boolean rather than an exact count.
|
||||
///
|
||||
/// Deliberately bypasses the typed `forgejo-api` client
|
||||
/// (`issue_get_comments_and_timeline`) rather than calling it directly:
|
||||
/// this endpoint answers an empty `--since` window with a JSON `null`
|
||||
/// body, and the typed client's generated response type is
|
||||
/// `Vec<TimelineComment>`, which fails to deserialize `null` at all — the
|
||||
/// single most common answer to "anything new since my last check?"
|
||||
/// turns into a hard error instead of an empty list. The sibling
|
||||
/// `issue_get_comments` endpoint `comments.rs`'s own `fetch_since` calls
|
||||
/// returns `[]` for the same case and never hits this. [`NullableVec`] is
|
||||
/// this codebase's existing, tested newtype for exactly this shape of
|
||||
/// problem — used the same way for reactions and blocking-issue lists —
|
||||
/// so this reuses it via [`Client::get_api_json`] rather than inventing a
|
||||
/// second null-tolerant path.
|
||||
fn fetch_since(
|
||||
client: &Client,
|
||||
number: u64,
|
||||
|
|
@ -253,16 +268,18 @@ fn fetch_since(
|
|||
limit: u64,
|
||||
) -> Result<(Vec<TimelineComment>, bool)> {
|
||||
let (owner, name) = client.owner_repo()?;
|
||||
let query = IssueGetCommentsAndTimelineQuery {
|
||||
since: Some(since),
|
||||
before: None,
|
||||
};
|
||||
let idx = index(number)?;
|
||||
let fetch_limit = limit.saturating_add(1);
|
||||
let (_, events) = client
|
||||
.api()
|
||||
.issue_get_comments_and_timeline(owner, name, index(number)?, query)
|
||||
.page_size(u32::try_from(fetch_limit).unwrap_or(u32::MAX))
|
||||
.send()?;
|
||||
let since_str = since
|
||||
.format(&Rfc3339)
|
||||
.context("format --since timestamp as RFC 3339")?;
|
||||
let fetch_limit_str = fetch_limit.to_string();
|
||||
let path = format!("/repos/{owner}/{name}/issues/{idx}/timeline");
|
||||
let events: NullableVec<TimelineComment> = client.get_api_json(
|
||||
&path,
|
||||
&[("since", since_str.as_str()), ("limit", &fetch_limit_str)],
|
||||
)?;
|
||||
let events = events.0;
|
||||
let limit = usize::try_from(limit).unwrap_or(usize::MAX);
|
||||
let more = events.len() > limit;
|
||||
let mut events = events;
|
||||
|
|
|
|||
Loading…
Reference in a new issue