1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
use std::cell::RefCell;
use std::collections::HashMap;
use std::rc::Rc;
use anyhow::format_err;
use crate::{
manifest::Manifest, package_id::PackageId, package_req::PackageReq,
package_source::PackageSource, test_package::PackageBuilder,
};
use super::PackageContents;
pub struct InMemoryRegistry {
storage: Storage,
}
impl InMemoryRegistry {
pub fn new() -> Self {
Self {
storage: Default::default(),
}
}
pub fn publish(&self, builder: PackageBuilder) {
let mut storage = self.storage.contents.borrow_mut();
let (manifest, contents) = builder.package();
let scope = storage
.entry(manifest.package.name.scope().to_owned())
.or_default();
let entries = scope
.entry(manifest.package.name.name().to_owned())
.or_default();
entries.push(PackageEntry { manifest, contents });
}
pub fn source(&self) -> InMemoryRegistrySource {
InMemoryRegistrySource {
storage: self.storage.clone(),
}
}
}
pub struct InMemoryRegistrySource {
storage: Storage,
}
impl PackageSource for InMemoryRegistrySource {
fn update(&self) -> anyhow::Result<()> {
Ok(())
}
fn query(&self, package_req: &PackageReq) -> anyhow::Result<Vec<Manifest>> {
let storage = self.storage.contents.borrow();
let scope = match storage.get(package_req.name().scope()) {
Some(scope) => scope,
None => return Ok(Vec::new()),
};
let entries = match scope.get(package_req.name().name()) {
Some(entries) => entries,
None => return Ok(Vec::new()),
};
let result = entries
.iter()
.filter(|entry| {
package_req
.version_req()
.matches(&entry.manifest.package.version)
})
.map(|entry| &entry.manifest)
.cloned()
.collect();
Ok(result)
}
fn download_package(&self, package_id: &PackageId) -> anyhow::Result<PackageContents> {
let storage = self.storage.contents.borrow();
let scope = storage
.get(package_id.name().scope())
.ok_or_else(|| format_err!("Package {} does not exist", package_id))?;
let manifests = scope
.get(package_id.name().name())
.ok_or_else(|| format_err!("Package {} does not exist", package_id))?;
let entry = manifests
.iter()
.find(|entry| &entry.manifest.package.version == package_id.version())
.ok_or_else(|| format_err!("Package {} does not exist", package_id))?;
Ok(entry.contents.clone())
}
}
struct PackageEntry {
manifest: Manifest,
contents: PackageContents,
}
#[derive(Clone, Default)]
struct Storage {
contents: Rc<RefCell<HashMap<String, HashMap<String, Vec<PackageEntry>>>>>,
}