libwally/
package_source.rs1mod in_memory;
2mod registry;
3mod test_registry;
4
5pub use self::in_memory::InMemoryRegistry;
6use self::in_memory::InMemoryRegistrySource;
7pub use self::registry::Registry;
8pub use self::test_registry::TestRegistry;
9
10use std::collections::HashMap;
11use std::path::PathBuf;
12
13use serde::Serialize;
14
15use crate::manifest::Manifest;
16use crate::package_contents::PackageContents;
17use crate::package_id::PackageId;
18use crate::package_req::PackageReq;
19
20#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize)]
21pub enum PackageSourceId {
22 DefaultRegistry,
23 Git(String),
24 Path(PathBuf),
25}
26
27#[derive(Clone)]
28pub struct PackageSourceMap {
29 sources: HashMap<PackageSourceId, Box<PackageSource>>,
30 source_order: Vec<PackageSourceId>,
31}
32
33impl PackageSourceMap {
34 pub fn new(default_registry: Box<PackageSource>) -> Self {
35 let mut sources = HashMap::new();
36 sources.insert(PackageSourceId::DefaultRegistry, default_registry);
37
38 Self {
39 sources,
40 source_order: vec![PackageSourceId::DefaultRegistry],
41 }
42 }
43
44 pub fn get(&self, id: &PackageSourceId) -> Option<&PackageSource> {
45 self.sources.get(id).map(|source| source.as_ref())
46 }
47
48 pub fn source_order(&self) -> &Vec<PackageSourceId> {
49 &self.source_order
50 }
51
52 pub fn add_fallbacks(&mut self) -> anyhow::Result<()> {
56 let mut source_index = 0;
57
58 while source_index < self.source_order.len() {
59 let registry = self.sources.get(&self.source_order[source_index]).unwrap();
60
61 for fallback in registry.fallback_sources()? {
62 if !self.source_order.contains(&fallback) {
64 let source: Box<PackageSource> = match &fallback {
65 PackageSourceId::Git(url) => {
66 Box::new(PackageSource::Registry(Registry::from_registry_spec(url)?))
67 }
68 PackageSourceId::Path(path) => {
69 Box::new(PackageSource::TestRegistry(TestRegistry::new(path.clone())))
70 }
71 PackageSourceId::DefaultRegistry => {
72 panic!("Default registry should never be added as a fallback source!")
73 }
74 };
75
76 self.sources.insert(fallback.clone(), source);
77 self.source_order.push(fallback);
78 }
79 }
80
81 source_index += 1;
82 }
83
84 Ok(())
85 }
86}
87
88pub trait PackageSourceProvider: Sync + Send + Clone {
89 fn update(&self) -> anyhow::Result<()>;
91
92 fn query(&self, package_req: &PackageReq) -> anyhow::Result<Vec<Manifest>>;
95
96 fn download_package(&self, package_id: &PackageId) -> anyhow::Result<PackageContents>;
99
100 fn fallback_sources(&self) -> anyhow::Result<Vec<PackageSourceId>>;
102}
103
104#[derive(Clone)]
105pub enum PackageSource {
106 InMemory(InMemoryRegistrySource),
107 Registry(Registry),
108 TestRegistry(TestRegistry),
109}
110
111impl PackageSourceProvider for PackageSource {
112 fn update(&self) -> anyhow::Result<()> {
113 match self {
114 PackageSource::InMemory(source) => source.update(),
115 PackageSource::Registry(source) => source.update(),
116 PackageSource::TestRegistry(source) => source.update(),
117 }
118 }
119
120 fn query(&self, package_req: &PackageReq) -> anyhow::Result<Vec<Manifest>> {
121 match self {
122 PackageSource::InMemory(source) => source.query(package_req),
123 PackageSource::Registry(source) => source.query(package_req),
124 PackageSource::TestRegistry(source) => source.query(package_req),
125 }
126 }
127
128 fn download_package(&self, package_id: &PackageId) -> anyhow::Result<PackageContents> {
129 match self {
130 PackageSource::InMemory(source) => source.download_package(package_id),
131 PackageSource::Registry(source) => source.download_package(package_id),
132 PackageSource::TestRegistry(source) => source.download_package(package_id),
133 }
134 }
135
136 fn fallback_sources(&self) -> anyhow::Result<Vec<PackageSourceId>> {
137 match self {
138 PackageSource::InMemory(source) => source.fallback_sources(),
139 PackageSource::Registry(source) => source.fallback_sources(),
140 PackageSource::TestRegistry(source) => source.fallback_sources(),
141 }
142 }
143}