use rattler_conda_types::package::CondaArchiveIdentifier;
use rattler_conda_types::PackageRecord;
use rattler_digest::{compute_bytes_digest, compute_url_digest, Md5Hash, Sha256, Sha256Hash};
use std::{
fmt::{Display, Formatter},
path::Path,
};
#[derive(Debug, Hash, Clone, Eq, PartialEq)]
pub struct CacheKey {
pub(crate) name: String,
pub(crate) version: String,
pub(crate) build_string: String,
pub(crate) sha256: Option<Sha256Hash>,
pub(crate) md5: Option<Md5Hash>,
pub(crate) origin_hash: Option<String>,
}
impl CacheKey {
pub fn with_sha256(mut self, sha256: Sha256Hash) -> Self {
self.sha256 = Some(sha256);
self
}
pub fn with_opt_sha256(mut self, sha256: Option<Sha256Hash>) -> Self {
self.sha256 = sha256;
self
}
pub fn with_md5(mut self, md5: Md5Hash) -> Self {
self.md5 = Some(md5);
self
}
pub fn with_opt_md5(mut self, md5: Option<Md5Hash>) -> Self {
self.md5 = md5;
self
}
pub fn with_url(mut self, url: url::Url) -> Self {
let url_hash = compute_url_digest::<Sha256>(url);
self.origin_hash = Some(format!("{url_hash:x}"));
self
}
pub fn with_path(mut self, path: &Path) -> Self {
let path_hash = compute_bytes_digest::<Sha256>(path.as_os_str().as_encoded_bytes());
self.origin_hash = Some(format!("{path_hash:x}"));
self
}
}
impl CacheKey {
pub fn sha256(&self) -> Option<Sha256Hash> {
self.sha256
}
pub fn md5(&self) -> Option<Md5Hash> {
self.md5
}
}
impl From<CondaArchiveIdentifier> for CacheKey {
fn from(pkg: CondaArchiveIdentifier) -> Self {
CacheKey {
name: pkg.identifier.name,
version: pkg.identifier.version,
build_string: pkg.identifier.build_string,
sha256: None,
md5: None,
origin_hash: None,
}
}
}
impl From<&PackageRecord> for CacheKey {
fn from(record: &PackageRecord) -> Self {
Self {
name: record.name.as_normalized().to_string(),
version: record.version.to_string(),
build_string: record.build.clone(),
sha256: record.sha256,
md5: record.md5,
origin_hash: None,
}
}
}
impl Display for CacheKey {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match &self.origin_hash {
Some(url_hash) => write!(
f,
"{}-{}-{}-{}",
&self.name, &self.version, &self.build_string, url_hash
),
None => write!(f, "{}-{}-{}", &self.name, &self.version, &self.build_string),
}
}
}