|
1 |
| -use std::collections::HashMap; |
2 |
| -use std::ops::DerefMut; |
3 |
| - |
4 | 1 | use anyhow::Result;
|
5 |
| -use itertools::Itertools; |
6 |
| -use tracing::trace; |
| 2 | +use async_trait::async_trait; |
7 | 3 |
|
8 |
| -use crate::core::source::Source; |
9 |
| -#[cfg(doc)] |
10 |
| -use crate::core::Workspace; |
11 |
| -use crate::core::{Config, ManifestDependency, Package, PackageId, SourceId, Summary}; |
12 |
| -use crate::sources::PathSource; |
| 4 | +use crate::core::{ManifestDependency, Package, PackageId, Summary}; |
13 | 5 |
|
14 | 6 | pub mod cache;
|
| 7 | +pub mod source_map; |
15 | 8 |
|
16 |
| -/// Source of information about a group of packages. |
17 |
| -pub struct Registry<'c> { |
18 |
| - config: &'c Config, |
19 |
| - sources: HashMap<SourceId, Box<dyn Source + 'c>>, |
20 |
| -} |
21 |
| - |
22 |
| -impl<'c> Registry<'c> { |
23 |
| - /// Preload the registry with already loaded [`Package`]s. |
24 |
| - /// |
25 |
| - /// For example, a [`Workspace`] may load packages during construction/parsing/early phases |
26 |
| - /// for various operations, and this preload step avoids doubly-loading and |
27 |
| - /// parsing packages on the filesystem by inserting them all into the registry |
28 |
| - /// with their in-memory formats. |
29 |
| - pub fn preloaded(packages: impl Iterator<Item = Package>, config: &'c Config) -> Self { |
30 |
| - let sources = packages |
31 |
| - .sorted_by_key(|pkg| pkg.id.source_id) |
32 |
| - .group_by(|pkg| pkg.id.source_id); |
33 |
| - let sources = sources.into_iter().map(|(source_id, packages)| { |
34 |
| - let packages = packages.collect::<Vec<_>>(); |
35 |
| - let source = PathSource::preloaded(&packages, config); |
36 |
| - let source: Box<dyn Source + 'c> = Box::new(source); |
37 |
| - (source_id, source) |
38 |
| - }); |
39 |
| - let sources = HashMap::from_iter(sources); |
40 |
| - |
41 |
| - Self { config, sources } |
42 |
| - } |
43 |
| - |
44 |
| - fn ensure_loaded(&mut self, source_id: SourceId) -> Result<&mut (dyn Source + 'c)> { |
45 |
| - // We can't use Entry API here because `load` usage of &self conflicts with it. |
46 |
| - #[allow(clippy::map_entry)] |
47 |
| - if !self.sources.contains_key(&source_id) { |
48 |
| - let source = self.load(source_id)?; |
49 |
| - self.sources.insert(source_id, source); |
50 |
| - } |
51 |
| - |
52 |
| - Ok(self.sources.get_mut(&source_id).unwrap().deref_mut()) |
53 |
| - } |
54 |
| - |
55 |
| - fn load(&self, source_id: SourceId) -> Result<Box<dyn Source + 'c>> { |
56 |
| - trace!("loading source: {source_id}"); |
57 |
| - source_id.load(self.config) |
58 |
| - } |
59 |
| - |
| 9 | +#[async_trait(?Send)] |
| 10 | +pub trait Registry { |
60 | 11 | /// Attempt to find the packages that match a dependency request.
|
61 |
| - pub async fn query(&mut self, dependency: &ManifestDependency) -> Result<Vec<Summary>> { |
62 |
| - let source = self.ensure_loaded(dependency.source_id)?; |
63 |
| - source.query(dependency).await |
64 |
| - } |
| 12 | + async fn query(&mut self, dependency: &ManifestDependency) -> Result<Vec<Summary>>; |
65 | 13 |
|
66 | 14 | /// Fetch full package by its ID.
|
67 |
| - pub async fn download(&mut self, package_id: PackageId) -> Result<Package> { |
68 |
| - let source = self.ensure_loaded(package_id.source_id)?; |
69 |
| - source.download(package_id).await |
70 |
| - } |
| 15 | + async fn download(&mut self, package_id: PackageId) -> Result<Package>; |
71 | 16 | }
|
0 commit comments