From 8449f6cd0c97f341f75ac3201499ebb0c2161e6b Mon Sep 17 00:00:00 2001 From: Florian Klink Date: Wed, 4 Jan 2023 16:20:42 +0100 Subject: feat(tvix/store): implement Nixpath::from_absolute_path This allows constructing a NixPath from an absolute path. It pops off the STORE_DIR prefix and the trailing slash and returns an error if it couldn't be found. Change-Id: Ib540e353c63cc247ac15e20414b0db2caf695ef4 Reviewed-on: https://cl.tvl.fyi/c/depot/+/7751 Tested-by: BuildkiteCI Reviewed-by: tazjin --- tvix/store/src/nixpath.rs | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) (limited to 'tvix') diff --git a/tvix/store/src/nixpath.rs b/tvix/store/src/nixpath.rs index ed0d39864d..e7329b527c 100644 --- a/tvix/store/src/nixpath.rs +++ b/tvix/store/src/nixpath.rs @@ -8,6 +8,11 @@ pub const DIGEST_SIZE: usize = 20; // manually and have an assert in the tests. pub const ENCODED_DIGEST_SIZE: usize = 32; +// The store dir prefix, without trailing slash. +// That's usually where the Nix store is mounted at. +pub const STORE_DIR: &str = "/nix/store"; +pub const STORE_DIR_WITH_SLASH: &str = "/nix/store/"; + /// Errors that can occur during the validation of name characters. #[derive(Debug, PartialEq, Eq, Error)] pub enum ParseNixPathError { @@ -17,6 +22,8 @@ pub enum ParseNixPathError { InvalidHashEncoding(DecodeError), #[error("Invalid name {0}")] InvalidName(String), + #[error("Tried to parse an absolute path which was missing the store dir prefix.")] + MissingStoreDir(), } #[derive(Debug, PartialEq, Eq)] @@ -55,6 +62,15 @@ impl NixPath { }) } + /// Construct a NixPath from an absolute store path string. + /// That is a string starting with the store prefix (/nix/store) + pub fn from_absolute_path(s: &str) -> Result { + match s.strip_prefix(STORE_DIR_WITH_SLASH) { + Some(s_stripped) => Self::from_string(s_stripped), + None => Err(ParseNixPathError::MissingStoreDir()), + } + } + fn validate_characters(s: &str) -> Result<(), ParseNixPathError> { for c in s.chars() { if c.is_ascii_alphanumeric() @@ -91,7 +107,7 @@ mod tests { use crate::nixbase32::NIXBASE32; use crate::nixpath::{DIGEST_SIZE, ENCODED_DIGEST_SIZE}; - use super::NixPath; + use super::{NixPath, ParseNixPathError}; #[test] fn encoded_digest_size() { @@ -141,4 +157,26 @@ mod tests { NixPath::from_string("00bgd045z0d4icpbc2yyz4gx48ak44lanet-tools-1.60_p20170221182432") .expect_err("No error raised."); } + + #[test] + fn absolute_path() { + let example_nix_path_str = + "00bgd045z0d4icpbc2yyz4gx48ak44la-net-tools-1.60_p20170221182432"; + let nixpath_expected = NixPath::from_string(&example_nix_path_str).expect("must parse"); + + let nixpath_actual = NixPath::from_absolute_path( + "/nix/store/00bgd045z0d4icpbc2yyz4gx48ak44la-net-tools-1.60_p20170221182432", + ) + .expect("must parse"); + + assert_eq!(nixpath_expected, nixpath_actual); + } + + #[test] + fn absolute_path_missing_prefix() { + assert_eq!( + ParseNixPathError::MissingStoreDir(), + NixPath::from_absolute_path("foobar-123").expect_err("must fail") + ); + } } -- cgit 1.4.1