Skip to main content

NuGetRegistry

Struct NuGetRegistry 

Source
pub struct NuGetRegistry { /* private fields */ }

Implementations§

Source§

impl NuGetRegistry

Source

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

Source

pub fn with_base( cache: Arc<HttpCache>, hop: &ResolvedHop, policy: Arc<RegistryAccessPolicy>, fallback_chain: Vec<Arc<NuGetRegistry>>, ) -> NuGetRegistry

Creates a NuGetRegistry client for one resolved NuGet.Config-declared feed (issue #523) — WorkspaceDeclared-tier so it fetches through Self::fetch’s origin-pinned transport and validates each service-index resource @id against policy.

fallback_chain is empty for every call except the head client Self::register_chain builds for a multi-hop chain — every other hop is a dead end with nothing further to fall through to. Its own alternates map starts empty and is never populated — only the root ever registers a chain.

Takes hop: &ResolvedHop, not a bare NuGetFeedUrl (issue #561, FR-016) — carrying the hop’s own credential and slot identity is unrepresentable to omit, closing the trap where NuGetConfig::resolve_source_for/resolved_chains could independently disagree on a hop’s credential data (both reach NuGetSourceChain::chain exclusively through NuGetConfig::valid_hops/hops_for_mapping_keys, which now build this same type).

Source

pub fn register_chain( root: &Arc<NuGetRegistry>, chain: &NuGetSourceChain, policy: &Arc<RegistryAccessPolicy>, )

Builds the full hop tree for one NuGetSourceChain and inserts the head into root.alternates under chain.key. Called only from NuGetEcosystem::parse_manifest, at parse time.

The implicit-public final hop (when chain.implicit_public_fallback is set) is a freshly-constructed Public-tier client pointed at root’s own service_index_url (never Arc::clone(root), which would create a root→alternates→head→fallback_chain→root reference cycle).

Issue #561 (S3/FR-016): a vacant slot is capacity-capped at MAX_ALTERNATE_REGISTRIES as before. An occupied slot whose currently-registered Self::chain_auth_digest differs from chain’s freshly-computed chain_auth_digest is replaced in place — rebuilt exactly like the vacant arm, then inserted over the old Arc. This is deliberately not gated by the capacity check (M4): replacing an already-occupied slot does not grow the map, and gating it would silently strand a credential rotation once the cap is hit — reintroducing the revoked-PAT staleness bug this replace arm exists to fix. Not LRU: chain.key is stored as DependencySource::AlternateRegistry.index inside already-parsed documents, and Self::alternate_client is a pure lookup with no re-registration path — evicting a key a live document still references would degrade that document’s every hover to PackageNotFound until re-parse.

Source

pub fn alternate_client(&self, index: &str) -> Option<Arc<NuGetRegistry>>

The registered client for index (a NuGetSourceChain::key), if any — read-only, performs no registration. Intentionally only ever meaningful on the root: a chain-hop leaf’s own alternates map is always empty by construction.

Source

pub async fn get_versions_typed( &self, name: &str, ) -> Result<Vec<NuGetVersion>, DepsError>

Fetches all available versions for name from the flat-container endpoint, sorted newest-first.

Delegates to Self::get_versions_typed_with with freshness disabled so the two paths cannot drift apart.

§Errors

Returns an error if the service index cannot be resolved or the flat-container request fails.

Source

pub async fn get_versions_typed_with( &self, name: &str, freshness_enabled: bool, ) -> Result<Vec<NuGetVersion>, DepsError>

Same as Self::get_versions_typed, but attaches NuGetVersion::published_at from the registration hive when freshness_enabled and the feed exposes a RegistrationsBaseUrl resource.

The flat-container fetch (version list) and the registration-index fetch (for publish times) are independent once the service index is resolved, so they run concurrently via tokio::join! rather than sequentially — this matters because complete_versions_generic is a per-keystroke completion path and HttpCache has no TTL, so every call revalidates over the network.

A registration-index fetch or parse failure degrades to no publish times, never to an error: the version list itself must be unaffected by a listing problem.

Both fetches go through HttpCache::get_cached_trusted_origin, scoped to the resolved PackageBaseAddress/RegistrationsBaseUrl respectively — not just the external registration pages publish_times_from_index walks. Every redirect this method’s requests can follow (index, flat container, registration index, and — down in publish_times_from_index — the page @ids the index itself supplies) is checked against its trusted prefix, since get_cached_trusted_origin selects a redirect-policy-scoped client — it does not itself validate the initial request URL. That initial URL’s safety instead comes from reject_dot_segment, which gates name before flat_container_url/registration_index_url are ever called (#365 M5).

§Errors

Returns an error if the service index cannot be resolved or the flat-container request fails.

Source

pub async fn unlisted_versions_for_hover( &self, name: &str, ) -> Result<HashSet<String>, DepsError>

Hover-only enrichment (D1, #451): returns the subset of name’s recent versions (the same HOVER_RECENT_VERSIONS-bounded window registration_enrichment_from_index walks) that the registry currently reports as unlisted.

Deliberately not wired into Self::get_versions_typed_with/NuGetVersion: that shared path backs get_versions_with, which both hover and complete_versions_generic (completion) call, and its results also feed the per-document version cache that inlay hints and diagnostics render from. Threading listed through deps_core::Version::removal_status there would make an unlisted version silently vanish from completion suggestions too (prepare_version_display_items filters on removal_status().blocks_resolution() unconditionally) — the wrong tradeoff the spec calls out. This method is instead called only from crate::ecosystem::NuGetEcosystem’s generate_hover override, so only a hover request ever pays for it.

Degrades to an empty set (never an error) on any fetch/parse failure, or when the feed has no RegistrationsBaseUrl resource at all — hover must still render the ordinary version list rather than disappear because this optional decoration failed.

§Errors

Returns an error only if name is rejected as a dot-segment or the service index itself cannot be resolved — both of which also fail the hover response’s main version fetch, so this never surfaces a distinct failure mode to the caller.

Source

pub async fn get_latest_matching_typed( &self, name: &str, req: &str, ) -> Result<Option<NuGetVersion>, DepsError>

Finds the highest version of name matching req (exact pin, interval notation, or floating pattern). Prerelease versions are excluded unless req itself is prerelease-bearing.

§Errors

Returns an error if the service index cannot be resolved or the flat-container request fails.

Source

pub async fn search_typed( &self, query: &str, limit: usize, ) -> Result<Vec<PackageInfo>, DepsError>

Searches the NuGet SearchQueryService for query, returning up to limit results.

§Errors

Returns an error if the service index cannot be resolved or the search request fails.

Trait Implementations§

Source§

impl Clone for NuGetRegistry

Source§

fn clone(&self) -> NuGetRegistry

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Registry for NuGetRegistry

Source§

fn get_versions_from<'a>( &'a self, name: &'a PackageName, source: &'a DependencySource, freshness: FreshnessSettings, ) -> Pin<Box<dyn Future<Output = Result<Vec<Box<dyn Version>>, DepsError>> + Send + 'a>>

Dispatches by source (issue #523): an AlternateRegistry whose index has a registered client routes through Self::get_versions_chained; one with no registered client is PackageNotFound, never a fall back to api.nuget.org (falling back would send a private package name to the public registry — the dependency confusion leak this feature closes). Every other source keeps today’s public-registry path unchanged.

Source§

fn get_latest_matching_from<'a>( &'a self, name: &'a PackageName, source: &'a DependencySource, req: &'a VersionReq, _minimum_stability: Option<&'a str>, ) -> Pin<Box<dyn Future<Output = Result<Option<Box<dyn Version>>, DepsError>> + Send + 'a>>

get_versions_from’s get_latest_matching-shaped counterpart — same dispatch, same “never fall back to api.nuget.org for an unregistered AlternateRegistry” invariant. The winning hop (first hop with a non-empty version list, chosen once by Self::get_versions_chained) is where req is matched — a hop with no match is terminal (Ok(None)), not a trigger to search later hops for a “better” match.

Source§

fn get_versions<'a>( &'a self, name: &'a PackageName, ) -> Pin<Box<dyn Future<Output = Result<Vec<Box<dyn Version>>, DepsError>> + Send + 'a>>

Fetches all available versions for a package. Read more
Source§

fn get_versions_with<'a>( &'a self, name: &'a PackageName, freshness: FreshnessSettings, ) -> Pin<Box<dyn Future<Output = Result<Vec<Box<dyn Version>>, DepsError>> + Send + 'a>>

Like get_versions, but lets a registry that can obtain Version::published_at only through an extra request gate that request behind freshness.enabled instead of always paying for it. Read more
Source§

fn get_latest_matching<'a>( &'a self, name: &'a PackageName, req: &'a VersionReq, ) -> Pin<Box<dyn Future<Output = Result<Option<Box<dyn Version>>, DepsError>> + Send + 'a>>

Finds the latest version matching a version requirement. Read more
Source§

fn search<'a>( &'a self, query: &'a str, limit: usize, ) -> Pin<Box<dyn Future<Output = Result<Vec<Box<dyn Metadata>>, DepsError>> + Send + 'a>>

Searches for packages by name or keywords. Read more
Source§

fn select_latest_matching( &self, versions: &[Box<dyn Version>], req: &VersionReq, ) -> Option<usize>

Index of the latest version in versions satisfying req, with no I/O. Read more
Source§

fn reports_yanked(&self) -> bool

Whether get_versions results carry meaningful per-version yank/deprecation data via Version::removal_status. Read more
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Downcast to concrete registry type for ecosystem-specific operations
Source§

fn get_latest_matching_with_context<'a>( &'a self, name: &'a PackageName, req: &'a VersionReq, minimum_stability: Option<&'a str>, ) -> Pin<Box<dyn Future<Output = Result<Option<Box<dyn Version>>, DepsError>> + Send + 'a>>

Like get_latest_matching, but lets a registry whose “latest matching” selection can be refined by ecosystem-specific manifest state (e.g. Composer’s minimum-stability field, #424) read it, alongside req. Read more
Source§

fn select_latest_matching_with_context( &self, versions: &[Box<dyn Version>], req: &VersionReq, minimum_stability: Option<&str>, ) -> Option<usize>

Like select_latest_matching, but lets a registry whose selection can be refined by ecosystem-specific manifest state (e.g. Composer’s minimum-stability field, #424) read it, alongside versions and req. See get_latest_matching_with_context for why minimum_stability is an opaque per-ecosystem string rather than a shared type. 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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

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

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

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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
§

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

§

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
§

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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

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

Source§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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.
§

impl<T> WithSubscriber for T

§

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
§

fn with_current_subscriber(self) -> WithDispatch<Self>

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