refactor(nix-compat/store_path): add from_name_and_digest_fixed

Allow constructing a StorePath with a fixed-size digest.

Change-Id: Id7d0b0152f6c55660a8973a02c84afa9188ce3ba
Reviewed-on: https://cl.tvl.fyi/c/depot/+/11144
Autosubmit: flokli <flokli@flokli.de>
Reviewed-by: John Ericson <git@johnericson.me>
Tested-by: BuildkiteCI
This commit is contained in:
Florian Klink 2024-03-14 14:22:16 +02:00 committed by clbot
parent 98e6936301
commit 142c72e070
2 changed files with 17 additions and 5 deletions

View file

@ -215,10 +215,21 @@ impl<'a> StorePathRef<'a> {
} }
/// Construct a [StorePathRef] from a name and digest. /// Construct a [StorePathRef] from a name and digest.
/// The name is validated, and the digest checked for size.
pub fn from_name_and_digest(name: &'a str, digest: &[u8]) -> Result<Self, Error> { pub fn from_name_and_digest(name: &'a str, digest: &[u8]) -> Result<Self, Error> {
let digest_fixed = digest.try_into().map_err(|_| Error::InvalidLength)?;
Self::from_name_and_digest_fixed(name, digest_fixed)
}
/// Construct a [StorePathRef] from a name and digest of correct length.
/// The name is validated.
pub fn from_name_and_digest_fixed(
name: &'a str,
digest: [u8; DIGEST_SIZE],
) -> Result<Self, Error> {
Ok(Self { Ok(Self {
name: validate_name(name.as_bytes())?, name: validate_name(name.as_bytes())?,
digest: digest.try_into().map_err(|_| Error::InvalidLength)?, digest,
}) })
} }

View file

@ -1,6 +1,6 @@
use crate::nixbase32; use crate::nixbase32;
use crate::nixhash::{CAHash, NixHash}; use crate::nixhash::{CAHash, NixHash};
use crate::store_path::{Error, StorePathRef, DIGEST_SIZE, STORE_DIR}; use crate::store_path::{Error, StorePathRef, STORE_DIR};
use data_encoding::HEXLOWER; use data_encoding::HEXLOWER;
use sha2::{Digest, Sha256}; use sha2::{Digest, Sha256};
use thiserror; use thiserror;
@ -154,10 +154,11 @@ fn build_store_path_from_fingerprint_parts<'a>(
"{ty}:sha256:{}:{STORE_DIR}:{name}", "{ty}:sha256:{}:{STORE_DIR}:{name}",
HEXLOWER.encode(inner_digest) HEXLOWER.encode(inner_digest)
); );
let digest: [u8; DIGEST_SIZE] = compress_hash(&Sha256::new_with_prefix(fingerprint).finalize());
// name validation happens in here. // name validation happens in here.
StorePathRef::from_name_and_digest(name, &digest) StorePathRef::from_name_and_digest_fixed(
name,
compress_hash(&Sha256::new_with_prefix(fingerprint).finalize()),
)
} }
/// This contains the Nix logic to create "text hash strings", which are used /// This contains the Nix logic to create "text hash strings", which are used