pub struct JsrRegistry { /* private fields */ }Expand description
Client for the JSR registry (jsr.io for package metadata, api.jsr.io for search).
Both endpoints are keyless (live-verified 2026-08-24) and are fetched through the
shared HttpCache, so no TTL tuning is needed (NFR-001): JSR sends a strong ETag,
and HttpCache revalidates via If-None-Match on every call regardless of the
Cache-Control: no-cache, no-store header JSR also sends.
Implementations§
Source§impl JsrRegistry
impl JsrRegistry
Sourcepub fn new(cache: Arc<HttpCache>) -> JsrRegistry
pub fn new(cache: Arc<HttpCache>) -> JsrRegistry
Creates a new JSR registry client with the given HTTP cache.
Sourcepub async fn get_versions(
&self,
scope: &str,
name: &str,
) -> Result<Vec<JsrVersion>, DepsError>
pub async fn get_versions( &self, scope: &str, name: &str, ) -> Result<Vec<JsrVersion>, DepsError>
Fetches all versions of @{scope}/{name} from meta.json.
Returns versions sorted newest-first (per Registry::get_versions’ contract) —
meta.json’s versions is a JSON object, and serde_json does not preserve
insertion order here (preserve_order is enabled only for deps-composer), so an
explicit semver-descending sort is required (C2).
published_at is populated directly from this same response’s per-version
createdAt field — no extra request, unlike npm (D10).
§Errors
Returns an error if the HTTP request fails, the response is not valid UTF-8/JSON,
or the package does not exist (mapped to DepsError::PackageNotFound). Also
returns DepsError::PackageNotFound up front, before any request is made, if
scope or name starts with . (S-L1) — such a segment would otherwise let
url::Url::parse normalize the request path away from the intended
/@scope/name/meta.json shape.
§Examples
let cache = Arc::new(HttpCache::new());
let registry = JsrRegistry::new(cache);
let versions = registry.get_versions("std", "fs").await.unwrap();
assert!(!versions.is_empty());Sourcepub async fn search(
&self,
query: &str,
limit: usize,
) -> Result<Vec<JsrPackage>, DepsError>
pub async fn search( &self, query: &str, limit: usize, ) -> Result<Vec<JsrPackage>, DepsError>
Searches JSR for packages matching query.
If query is scope-qualified ("@scope/pkg-prefix"), the scope is split off
before hitting the wire and only the package-name portion is sent as the search
text (N1): JSR’s search API ranks purely by text relevance and ignores the scope
portion of a scoped query entirely — live-verified 2026-08-24, query=@std/fs
buries the exact std/fs match 17th of 20 results, and a scope= query parameter
is accepted but has no effect on ranking. Results are then reordered so an exact
scope match sorts first (a stable sort, so JSR’s own relevance ranking is preserved
within each group), restoring the ordering a caller completing a scoped specifier —
the common case for JSR — actually needs.
§Errors
Returns an error if the HTTP request fails or the response is not valid JSON.
§Examples
let cache = Arc::new(HttpCache::new());
let registry = JsrRegistry::new(cache);
let results = registry.search("fs", 10).await.unwrap();
assert!(!results.is_empty());Trait Implementations§
Source§impl Clone for JsrRegistry
impl Clone for JsrRegistry
Source§fn clone(&self) -> JsrRegistry
fn clone(&self) -> JsrRegistry
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
impl !RefUnwindSafe for JsrRegistry
impl !UnwindSafe for JsrRegistry
impl Freeze for JsrRegistry
impl Send for JsrRegistry
impl Sync for JsrRegistry
impl Unpin for JsrRegistry
impl UnsafeUnpin for JsrRegistry
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> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
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