use std::path::{Path, PathBuf};
use crate::{channel::UserChannel, identity::InstallationId, state::PublicationId};
pub fn state_path(home: &Path) -> PathBuf {
home.join("state").with_extension("json")
}
pub fn manifest_cache(home: &Path) -> PathBuf {
home.join("channel-manifest").with_extension("json")
}
pub fn cargo_build_cache(home: &Path) -> PathBuf {
home.join("cache").join("cargo")
}
pub fn cargo_source_cache(build_cache: &Path, canonical: &Path) -> PathBuf {
use sha2::Digest as _;
let digest = sha2::Sha256::digest(canonical.as_os_str().as_encoded_bytes());
let mut key = String::with_capacity(64);
for byte in digest {
use std::fmt::Write;
write!(&mut key, "{byte:02x}").expect("writing to a String cannot fail");
}
build_cache.join(key)
}
pub fn toolchains_dir(home: &Path) -> PathBuf {
home.join("toolchains")
}
pub fn toolchain_link(home: &Path, channel: &semver::Version) -> PathBuf {
installation_link(home, &InstallationId::Version(channel.clone()))
}
pub fn installation_link(home: &Path, id: &InstallationId) -> PathBuf {
match id {
InstallationId::Version(version) => toolchains_dir(home).join(version.to_string()),
InstallationId::Custom(name) => toolchains_dir(home).join("custom").join(name.as_ref()),
}
}
pub fn network_link(home: &Path, network: &str) -> PathBuf {
toolchains_dir(home).join(network)
}
pub fn publications_dir(home: &Path) -> PathBuf {
home.join("publications")
}
pub fn var_dir(home: &Path, selector: &UserChannel) -> PathBuf {
match selector {
UserChannel::Custom(name) => home.join("var").join("custom").join(name.as_ref()),
_ => home.join("var").join(selector.to_string()),
}
}
pub fn journal_dir(home: &Path) -> PathBuf {
home.join("journal")
}
pub fn publication_dir(home: &Path, channel: &semver::Version, id: &PublicationId) -> PathBuf {
publications_dir(home).join(format!("{channel}-{id}"))
}
pub fn runtime_var_dir(home: &Path, selector: &UserChannel, source: &UserChannel) -> PathBuf {
let root = var_dir(home, selector);
if !matches!(selector, UserChannel::Custom(_)) {
return root;
}
match source {
UserChannel::Named(network) => root.join("networks").join(network.as_ref()),
UserChannel::Version(_) => root.join("pinned"),
UserChannel::Custom(_) => {
unreachable!("custom installation sources must be upstream selectors")
},
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn retained_named_data_is_partitioned_by_network() {
let home = Path::new("/midenup");
let custom: UserChannel = "custom:dev".parse().unwrap();
let mainnet: UserChannel = "mainnet".parse().unwrap();
let testnet: UserChannel = "testnet".parse().unwrap();
let pinned: UserChannel = "0.15.0".parse().unwrap();
assert_eq!(
runtime_var_dir(home, &custom, &mainnet),
Path::new("/midenup/var/custom/dev/networks/mainnet")
);
assert_eq!(
runtime_var_dir(home, &custom, &testnet),
Path::new("/midenup/var/custom/dev/networks/testnet")
);
assert_eq!(
runtime_var_dir(home, &custom, &pinned),
Path::new("/midenup/var/custom/dev/pinned")
);
assert_eq!(runtime_var_dir(home, &mainnet, &pinned), Path::new("/midenup/var/mainnet"));
assert_eq!(var_dir(home, &custom), Path::new("/midenup/var/custom/dev"));
}
}