feat(nix-compat/store_path): add StorePathRef
Change-Id: I0d888a55d93e5c22e77cb0264d09757656f731d7 Reviewed-on: https://cl.tvl.fyi/c/depot/+/9862 Tested-by: BuildkiteCI Reviewed-by: flokli <flokli@flokli.de>
This commit is contained in:
parent
621739037f
commit
50aa74a59c
1 changed files with 72 additions and 22 deletions
|
@ -96,28 +96,7 @@ impl StorePath {
|
|||
/// Construct a [StorePath] by passing the `$digest-$name` string
|
||||
/// that comes after [STORE_DIR_WITH_SLASH].
|
||||
pub fn from_bytes(s: &[u8]) -> Result<StorePath, Error> {
|
||||
// the whole string needs to be at least:
|
||||
//
|
||||
// - 32 characters (encoded hash)
|
||||
// - 1 dash
|
||||
// - 1 character for the name
|
||||
if s.len() < ENCODED_DIGEST_SIZE + 2 {
|
||||
Err(Error::InvalidLength)?
|
||||
}
|
||||
|
||||
let digest = match nixbase32::decode(&s[..ENCODED_DIGEST_SIZE]) {
|
||||
Ok(decoded) => decoded,
|
||||
Err(decoder_error) => return Err(Error::InvalidHashEncoding(decoder_error)),
|
||||
};
|
||||
|
||||
if s[ENCODED_DIGEST_SIZE] != b'-' {
|
||||
return Err(Error::MissingDash);
|
||||
}
|
||||
|
||||
Ok(StorePath {
|
||||
name: validate_name(&s[ENCODED_DIGEST_SIZE + 1..])?.to_owned(),
|
||||
digest: digest.try_into().expect("size is known"),
|
||||
})
|
||||
Ok(StorePathRef::from_bytes(s)?.into())
|
||||
}
|
||||
|
||||
/// Construct a [StorePath] from an absolute store path string.
|
||||
|
@ -175,6 +154,71 @@ impl StorePath {
|
|||
}
|
||||
}
|
||||
|
||||
/// Like [StorePath], but without a heap allocation for the name.
|
||||
/// Used by [StorePath] for parsing.
|
||||
///
|
||||
/// TODO(edef): migrate most methods here
|
||||
#[derive(Debug)]
|
||||
pub struct StorePathRef<'a> {
|
||||
digest: [u8; DIGEST_SIZE],
|
||||
name: &'a str,
|
||||
}
|
||||
|
||||
impl From<StorePathRef<'_>> for StorePath {
|
||||
fn from(StorePathRef { digest, name }: StorePathRef<'_>) -> Self {
|
||||
StorePath {
|
||||
digest,
|
||||
name: name.to_owned(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a StorePath> for StorePathRef<'a> {
|
||||
fn from(&StorePath { digest, ref name }: &'a StorePath) -> Self {
|
||||
StorePathRef {
|
||||
digest,
|
||||
name: name.as_ref(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> StorePathRef<'a> {
|
||||
pub fn digest(&self) -> &[u8; DIGEST_SIZE] {
|
||||
&self.digest
|
||||
}
|
||||
|
||||
pub fn name(&self) -> &'a str {
|
||||
self.name
|
||||
}
|
||||
|
||||
/// Construct a [StorePathRef] by passing the `$digest-$name` string
|
||||
/// that comes after [STORE_DIR_WITH_SLASH].
|
||||
pub fn from_bytes(s: &'a [u8]) -> Result<Self, Error> {
|
||||
// the whole string needs to be at least:
|
||||
//
|
||||
// - 32 characters (encoded hash)
|
||||
// - 1 dash
|
||||
// - 1 character for the name
|
||||
if s.len() < ENCODED_DIGEST_SIZE + 2 {
|
||||
Err(Error::InvalidLength)?
|
||||
}
|
||||
|
||||
let digest = match nixbase32::decode(&s[..ENCODED_DIGEST_SIZE]) {
|
||||
Ok(decoded) => decoded,
|
||||
Err(decoder_error) => return Err(Error::InvalidHashEncoding(decoder_error)),
|
||||
};
|
||||
|
||||
if s[ENCODED_DIGEST_SIZE] != b'-' {
|
||||
return Err(Error::MissingDash);
|
||||
}
|
||||
|
||||
Ok(StorePathRef {
|
||||
digest: digest.try_into().expect("size is known"),
|
||||
name: validate_name(&s[ENCODED_DIGEST_SIZE + 1..])?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// NAME_CHARS contains `true` for bytes that are valid in store path names,
|
||||
/// not accounting for '.' being permitted only past the first character.
|
||||
static NAME_CHARS: [bool; 256] = {
|
||||
|
@ -231,6 +275,12 @@ pub(crate) fn validate_name(s: &(impl AsRef<[u8]> + ?Sized)) -> Result<&str, Err
|
|||
}
|
||||
|
||||
impl fmt::Display for StorePath {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
StorePathRef::from(self).fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for StorePathRef<'_> {
|
||||
/// The string representation of a store path starts with a digest (20
|
||||
/// bytes), [crate::nixbase32]-encoded, followed by a `-`,
|
||||
/// and ends with the name.
|
||||
|
|
Loading…
Reference in a new issue