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
use semver::Version;
use serde::{Deserialize, Serialize};
/// All the artifacts that the [Component] contains.
#[derive(Serialize, Deserialize, Debug, Clone, Hash)]
pub struct Artifacts {
artifacts: Vec<Artifact>,
}
impl Artifacts {
/// Get a URI to download an artifact that's valid for `target`.
pub fn get_uri_for(&self, target: &TargetTriple) -> Option<String> {
self.artifacts.iter().find_map(|artifact| artifact.get_uri_for(target))
}
/// Replace all occurrances of version string `prev` with `replacement` in all artifact URIs
pub fn replace_version(&mut self, prev: &Version, replacement: &Version) {
let prev = prev.to_string();
let replacement = replacement.to_string();
for artifact in self.artifacts.iter_mut() {
if artifact.0.contains(&prev) {
let modified = artifact.0.replace(&prev, &replacement);
artifact.0 = modified;
}
}
}
}
/// Holds a URI used to fetch an artifact.
///
/// These URIs have the following format: `(https://|file://)<path>/<component name>(-<triplet>|.masp)`
#[derive(Serialize, Deserialize, Debug, Clone, Hash)]
struct Artifact(String);
#[derive(Debug, PartialEq)]
pub enum TargetTriple {
/// Custom triplet used by cargo. Since we use the same triplets as cargo, we simply copy them
/// as-is, without any type of parsing.
Custom(String),
/// Used for .masp libraries that are used in Miden VM.
///
/// Components that have these libraries as artifacts only have one entry in
/// [`Artifacts::artifacts`].
MidenVM,
}
impl TargetTriple {
fn get_uri_extension(&self) -> String {
match &self {
Self::MidenVM => String::from(".masp"),
Self::Custom(triplet) => triplet.to_string(),
}
}
}
impl Artifact {
/// Returns the URI for the specified component + triplet if it has it.
///
/// NOTE: The component name is required to separate the triplet from the filename in the URI.
fn get_uri_for(&self, target: &TargetTriple) -> Option<String> {
#[allow(clippy::question_mark)]
let path = if let Some(file_path) = self.0.strip_prefix("file://") {
file_path
} else {
self.0.strip_prefix("https://")?
};
// <component name>(-<triplet>|.masp)
let uri_extension = path.split("/").last()?;
let wanted_uri_extension = target.get_uri_extension();
if uri_extension.contains(&wanted_uri_extension) {
Some(self.0.clone())
} else {
None
}
}
}