pub struct GitHubFetch {
pub link: BranchLink,
pub link_slug: Option<String>,
/* private fields */
}Expand description
GitHub fetch state slice of the TUI App (issue #128; threading on
the async-task spine since #255).
See the module docs for the full contract; the short version is:
App checks Self::is_cached, marks Self::mark_loading before
spawning the gh worker on the super::async_task::TaskRunner
spine, and stamps the terminal result back via
Self::complete_issue / Self::complete_pr once the spine
confirms the worker’s generation is still authoritative.
Fields§
§link: BranchLink§link_slug: Option<String>Implementations§
Source§impl GitHubFetch
impl GitHubFetch
Sourcepub fn new() -> Self
pub fn new() -> Self
Construct an empty GitHubFetch with no link, no slug, and empty
per-key caches. The App constructor calls this once and then
immediately runs Self::refresh_link against the repo so the
cold state lasts only as long as the constructor itself.
Sourcepub fn refresh_link(&mut self, repo: &Repository, branch: Option<&str>)
pub fn refresh_link(&mut self, repo: &Repository, branch: Option<&str>)
Re-read the link for branch against repo, re-resolve the
repo slug from the origin remote, and reset every cached
fetch state. Called by App::refresh_link after the user
navigates to a different worktree — the cached state refers to a
different (issue, pr) tuple and would be misleading if reused.
(App::refresh_link separately drops any in-flight GitHub worker
on the spine — see Self::invalidate for the pairing.)
Sourcepub fn invalidate(&mut self)
pub fn invalidate(&mut self)
Flush every cached fetch state. Equivalent to “the cached
(issue, pr) tuples are no longer authoritative”. Called by
Self::refresh_link; exposed standalone for callers (e.g. an
explicit “force refresh” key like F) that want to wipe the cache
without re-reading the link.
Post-#255 this clears only the result cache. Dropping any in-
flight worker’s late result is the spine’s job: the App pairs
every invalidate() with a
TaskRunner::invalidate_matching(is_github)
so the stale generation is bumped and its result discarded by
TaskRunner::complete.
That pairing is the navigation invariant — cache clear and spine
generation-bump always move together.
Sourcepub fn apply_detected_pr(&mut self, detected: Option<u64>)
pub fn apply_detected_pr(&mut self, detected: Option<u64>)
Stamp an auto-detected PR onto the resolved link when none is
already linked (issue #181). Pure: the App orchestrator owns the
gh pr list --head <branch> shell-out and feeds the detected number
here so the sidebar’s pr_fetch_state() can resolve it. Delegates
to github::apply_detected_pr, so an explicit gwm link --pr
(already on link.pr) always wins and the result is marked
LinkSource::Detected. This only mutates in-memory state; the App
separately persists the detection via
github::persist_detected_pr (issue #283) so the table read path
picks it up.
Sourcepub fn clear_detected_pr(&mut self)
pub fn clear_detected_pr(&mut self)
Drop a previously auto-detected PR so the next refresh re-resolves
it from GitHub (issue #181 — the detected link is “resolved live”,
so a PR that was opened/closed/replaced while sitting on the same
worktree must not stick across F presses). A no-op for an
explicit (gwm link --pr) or branch-name link — those stay pinned.
Sourcepub fn mark_loading(&mut self, key: FetchKey)
pub fn mark_loading(&mut self, key: FetchKey)
Flip the per-key cache entry for key to
GitHubFetchState::Loading (issue #255). Called by the App
after it has claimed a generation from the spine and is about to
spawn the gh worker, so the sidebar paints a “…loading” badge and
App::is_github_loading reads true until the
terminal result lands. Pure: coalescing (skip the spawn if a worker
is already running) is the spine’s call, not this module’s.
Sourcepub fn is_cached(&self, key: FetchKey) -> bool
pub fn is_cached(&self, key: FetchKey) -> bool
true when the per-key cache already carries a terminal Loaded
or Error for key (issue #255). The App consults this before
claiming a spine generation so an explicit-but-already-warm key
skips a redundant gh spawn. The (target, number) identity is
the cache key: Issue(42) / Pr(42) / Issue(43) are all
independent (post-#138).
Sourcepub fn complete_issue(
&mut self,
number: u64,
result: Result<IssueStatus, String>,
)
pub fn complete_issue( &mut self, number: u64, result: Result<IssueStatus, String>, )
Stamp the terminal outcome of an issue fetch into the per-key cache
(issue #255). Pure cache write — Ok → Loaded, Err → Error,
keyed by number. After this call,
Self::is_cached(Issue(number)) returns true.
Post-#255 there is no late-result guard here: the drop decision for
a superseded worker lives on the spine
(TaskRunner::complete),
which the App checks before calling this. So by the time we
stamp, the result is already known authoritative.
Sourcepub fn complete_pr(&mut self, number: u64, result: Result<PrStatus, String>)
pub fn complete_pr(&mut self, number: u64, result: Result<PrStatus, String>)
PR-side counterpart to Self::complete_issue — pure cache write,
no late-result guard (the spine owns that since #255).
Sourcepub fn apply_issue_result(&mut self, r: Result<IssueStatus, String>)
pub fn apply_issue_result(&mut self, r: Result<IssueStatus, String>)
Stamp the issue fetch state from a fetch result. Ok(s) →
Loaded(s) (keyed by s.number), Err(msg) → Error(msg)
(keyed by the current link.issue if any). Test-friendly
wrapper used by App::apply_issue_fetch_result; the helper is for
tests that stamp state directly without going through the spine’s
request → complete generation flow.
If Err is given and no link issue is set, the helper is a
no-op (there’s no number to key by). Tests that exercise the
error path should set up a branch link first via
make_app_on_branch("feat/#<n>-…").
Sourcepub fn apply_pr_result(&mut self, r: Result<PrStatus, String>)
pub fn apply_pr_result(&mut self, r: Result<PrStatus, String>)
PR-side counterpart to Self::apply_issue_result. Same
no-op-on-Err-without-link contract.
Sourcepub fn issue_fetch_state(&self, number: u64) -> &GitHubFetchState<IssueStatus>
pub fn issue_fetch_state(&self, number: u64) -> &GitHubFetchState<IssueStatus>
Read the cached fetch state for Issue(number). Returns
&GitHubFetchState::Idle for absent keys via a 'static
constant so the borrow is cheap and lifetime-free. Used by the
renderer (src/tui/ui.rs) and the App-level wrapper
App::issue_fetch_state to read the cache without leaking the
per-key map shape.
Sourcepub fn pr_fetch_state(&self, number: u64) -> &GitHubFetchState<PrStatus>
pub fn pr_fetch_state(&self, number: u64) -> &GitHubFetchState<PrStatus>
PR-side counterpart to Self::issue_fetch_state.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for GitHubFetch
impl RefUnwindSafe for GitHubFetch
impl Send for GitHubFetch
impl Sync for GitHubFetch
impl Unpin for GitHubFetch
impl UnsafeUnpin for GitHubFetch
impl UnwindSafe for GitHubFetch
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more