Skip to main content

uv_cache/
archive.rs

1use std::convert::Infallible;
2use std::path::{Path, PathBuf};
3use std::str::FromStr;
4
5/// A unique identifier for an archive (unzipped wheel) in the cache.
6///
7/// Note: for compatibility with the existing `archive-v0` bucket, this is a newtype
8/// around a `String` instead of a newtype around `uv_fastid::Id`. In the future,
9/// we may want to bump to `archive-v1` and switch to using `uv_fastid::Id` directly.
10#[derive(Debug, Clone, Eq, PartialEq, Hash, serde::Serialize, serde::Deserialize)]
11pub struct ArchiveId(String);
12
13/// A unique identifier for a file stored in the archive file bucket.
14#[derive(Debug, Clone, Eq, PartialEq, Hash)]
15pub struct ArchiveFileId(PathBuf);
16
17impl Default for ArchiveId {
18    fn default() -> Self {
19        Self::new()
20    }
21}
22
23impl ArchiveId {
24    /// Generate a new unique identifier for an archive.
25    pub(crate) fn new() -> Self {
26        Self(uv_fastid::Id::secure().to_string())
27    }
28
29    /// Use a path-safe digest as the complete archive identifier.
30    ///
31    /// This does not generate or hash an identifier. Callers must ensure that the digest uniquely
32    /// identifies the persisted directory contents.
33    pub fn from_digest(digest: String) -> Self {
34        Self(digest)
35    }
36}
37
38impl ArchiveFileId {
39    /// Identify a file object by a digest that includes its contents and executable status.
40    pub fn from_digest(digest: &str) -> Self {
41        let shard = digest.get(..2).unwrap_or(digest);
42        Self(PathBuf::from(shard).join(digest))
43    }
44}
45
46impl AsRef<Path> for ArchiveFileId {
47    fn as_ref(&self) -> &Path {
48        &self.0
49    }
50}
51
52impl AsRef<Path> for ArchiveId {
53    fn as_ref(&self) -> &Path {
54        self.0.as_ref()
55    }
56}
57
58impl std::fmt::Display for ArchiveId {
59    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
60        self.0.fmt(f)
61    }
62}
63
64impl FromStr for ArchiveId {
65    type Err = Infallible;
66
67    fn from_str(s: &str) -> Result<Self, Self::Err> {
68        Ok(Self(s.to_string()))
69    }
70}