Skip to main content

DepsDevClient

Struct DepsDevClient 

Source
pub struct DepsDevClient { /* private fields */ }
Expand description

Assembles SupplyChainTrustSignals from deps.dev’s two-call sequence.

Layers its own TTL memo over HttpCache’s reused transport — see the module docs for the caching/failure-handling rationale.

Implementations§

Source§

impl DepsDevClient

Source

pub fn new(cache: Arc<HttpCache>) -> Self

Creates a client that reuses cache’s HTTP transport for both deps.dev calls, pointed at the real deps.dev API.

Source

pub async fn trust_signal( &self, system: DepsDevSystem, name: &str, version: &str, ) -> Option<SupplyChainTrustSignal>

Returns the supply-chain trust signal for one resolved (system, name, version), or None when nothing is available to render.

Infallible by construction (FR-006) — every failure degrades to None, memoized under the short error TTL so a transient outage does not re-fire on every hover. A call for a key another concurrent call is already fetching awaits that leader’s result via coalesce rather than returning None immediately (issue #1454).

Source

pub async fn typosquat_signal( &self, system: DepsDevSystem, name: &str, ) -> (Option<TyposquatSignal>, FetchCompleteness)

Returns a typosquat-suspect signal for one declared dependency (issue #1437, spec 071), or None when nothing clears the ratio gate, paired with whether every deps.dev call this evaluation needed actually completed (issue #1463) — see FetchCompleteness.

Infallible by construction (NFR-001/FR-005), exactly like Self::trust_signal: every failure at any stage — a below-threshold ratio included — degrades to None, never a propagated error. FetchCompleteness::Incomplete is the caller-facing signal that a None/empty degradation of this specific kind happened; it does not itself change what this function returns as the signal. Does not itself check system/ecosystem coverage or any config opt-in switch; callers (lsp_helpers::diagnostics::fetch_typosquat_signals) are responsible for only calling this for a system deps_dev_system actually maps to, and only when the feature is enabled (FR-002/FR-009) — mirroring how Self::trust_signal itself never checks ecosystem coverage either.

Source

pub async fn gossip_findings_batch( &self, system: DepsDevSystem, names: &[String], ) -> HashMap<String, GossipFindings>

Returns GOSSIP cooldown/low-usage findings for every name in names whose package-level defaultVersion carries a resolvable result (issue #1456, spec 072) — one POST /v3alpha/findingsbatch call for the memo-misses, never one call per name.

A name already served from Self::gossip’s memo (within GOSSIP_SUCCESS_TTL/ GOSSIP_ERROR_TTL) contributes nothing to the outbound request and lands directly in the returned map. A name already claimed by another concurrent call to this method is skipped by this call rather than fetched a second time (mirrors Self::similar_packages’s identical in-flight trade-off) — the claiming call’s own memo write is what the losing caller’s next prefetch trigger will see, rather than this call joining that in-flight fetch directly.

The returned map only ever contains a name when GOSSIP reported a resolvable defaultVersion for it — a name with no resolvable default version (e.g. a package-level NOT_FOUND) is simply absent, not present with an empty GossipFindings (NFR-002).

Does not itself check system/ecosystem coverage or any config opt-in switch — mirrors every other public method on this client (see Self::typosquat_signal’s doc for why that’s the caller’s responsibility).

Source

pub async fn force_refresh_gossip_findings( &self, system: DepsDevSystem, names: &[String], ) -> HashMap<String, GossipFindings>

Force-refetches GOSSIP findings for names, bypassing whatever the per-package memo currently holds (issue #1456, spec 072 FR-011/M21a) — the counterpart to Self::gossip_findings_batch’s normal, memo-respecting path, for a caller that has already detected a genuine staleness signal (a version-equality mismatch, FR-008) and knows a memo-respecting call would just return the same stale answer.

Each name is independently throttled to at most once every GOSSIP_REFRESH_BACKOFF (M21a) via Self::gossip_last_refresh_attempt — a name still within its backoff window is silently skipped (absent from the returned map, exactly like a name with no resolvable defaultVersion), so a caller does not need its own throttling logic on top of this. Does not itself decide which packages need refreshing, which documents to republish for, or filter for privacy — see deps-lsp::document::gossip_prefetch’s mismatch-detection function (M21b/M21c), the sole intended caller, which owns the source_is_public_registry_content gate.

Code-review C1-mirroring fix (finding #4): the backoff check-then-write is not two independent DashMap operations here — Self::gossip_refresh_in_flight claims each name for the whole check/evict/fetch/store sequence, so two concurrent calls for the same package can never both observe “not throttled” before either writes; the loser simply skips that name this round (mirrors Self::gossip_in_flight’s identical claim-before-fetch shape). Also acquires Self::gossip_semaphore before fetching (finding #3) — without it, this path bypassed FR-012/N8’s global concurrency cap entirely, since it calls Self::fetch_gossip_batch directly rather than going through Self::gossip_findings_batch (which already acquires it).

Source

pub async fn gossip_findings_for_version( &self, system: DepsDevSystem, name: &str, version: &str, ) -> Option<GossipFindings>

Returns GOSSIP findings for one exact, resolved (system, name, version) — hover’s only live, per-request GOSSIP fetch (issue #1456, spec 072 FR-005): the pinned/resolved version may not be the package’s defaultVersion, so Self::gossip_findings_batch’s package-level result cannot cover it.

Infallible by construction, exactly like Self::trust_signal: every failure degrades to None, memoized under GOSSIP_ERROR_TTL so a transient outage does not re-fire on every hover. Backed by Self::gossip_versions (version-keyed, not Self::gossip’s package-level memo) so a response landing past hover’s GOSSIP_WAIT_BUDGET (lsp_helpers::hover) still warms something usable by the next hover on the same pinned version, mirroring Self::trust_signal’s spawn-and-warm design.

Trait Implementations§

Source§

impl Debug for DepsDevClient

Manual, non-exhaustive impl: VersionData derives Debug and holds this behind Option<&Arc<DepsDevClient>>, but the memo maps’ entry types have no reason to derive Debug of their own.

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more