aboutsummaryrefslogtreecommitdiff
path: root/nix-rust/src/store/path.rs
diff options
context:
space:
mode:
Diffstat (limited to 'nix-rust/src/store/path.rs')
-rw-r--r--nix-rust/src/store/path.rs224
1 files changed, 0 insertions, 224 deletions
diff --git a/nix-rust/src/store/path.rs b/nix-rust/src/store/path.rs
deleted file mode 100644
index 99f7a1f18..000000000
--- a/nix-rust/src/store/path.rs
+++ /dev/null
@@ -1,224 +0,0 @@
-use crate::error::Error;
-use crate::util::base32;
-use std::fmt;
-use std::path::Path;
-
-#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
-pub struct StorePath {
- pub hash: StorePathHash,
- pub name: StorePathName,
-}
-
-pub const STORE_PATH_HASH_BYTES: usize = 20;
-pub const STORE_PATH_HASH_CHARS: usize = 32;
-
-impl StorePath {
- pub fn new(path: &Path, store_dir: &Path) -> Result<Self, Error> {
- if path.parent() != Some(store_dir) {
- return Err(Error::NotInStore(path.into()));
- }
- Self::new_from_base_name(
- path.file_name()
- .ok_or_else(|| Error::BadStorePath(path.into()))?
- .to_str()
- .ok_or_else(|| Error::BadStorePath(path.into()))?,
- )
- }
-
- pub fn from_parts(hash: [u8; STORE_PATH_HASH_BYTES], name: &str) -> Result<Self, Error> {
- Ok(StorePath {
- hash: StorePathHash(hash),
- name: StorePathName::new(name)?,
- })
- }
-
- pub fn new_from_base_name(base_name: &str) -> Result<Self, Error> {
- if base_name.len() < STORE_PATH_HASH_CHARS + 1
- || base_name.as_bytes()[STORE_PATH_HASH_CHARS] != b'-'
- {
- return Err(Error::BadStorePath(base_name.into()));
- }
-
- Ok(StorePath {
- hash: StorePathHash::new(&base_name[0..STORE_PATH_HASH_CHARS])?,
- name: StorePathName::new(&base_name[STORE_PATH_HASH_CHARS + 1..])?,
- })
- }
-}
-
-impl fmt::Display for StorePath {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "{}-{}", self.hash, self.name)
- }
-}
-
-#[derive(Clone, PartialEq, Eq, Debug)]
-pub struct StorePathHash([u8; STORE_PATH_HASH_BYTES]);
-
-impl StorePathHash {
- pub fn new(s: &str) -> Result<Self, Error> {
- assert_eq!(s.len(), STORE_PATH_HASH_CHARS);
- let v = base32::decode(s)?;
- assert_eq!(v.len(), STORE_PATH_HASH_BYTES);
- let mut bytes: [u8; 20] = Default::default();
- bytes.copy_from_slice(&v[0..STORE_PATH_HASH_BYTES]);
- Ok(Self(bytes))
- }
-
- pub fn hash(&self) -> &[u8; STORE_PATH_HASH_BYTES] {
- &self.0
- }
-}
-
-impl fmt::Display for StorePathHash {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- let mut buf = vec![0; STORE_PATH_HASH_CHARS];
- base32::encode_into(&self.0, &mut buf);
- f.write_str(std::str::from_utf8(&buf).unwrap())
- }
-}
-
-impl Ord for StorePathHash {
- fn cmp(&self, other: &Self) -> std::cmp::Ordering {
- // Historically we've sorted store paths by their base32
- // serialization, but our base32 encodes bytes in reverse
- // order. So compare them in reverse order as well.
- self.0.iter().rev().cmp(other.0.iter().rev())
- }
-}
-
-impl PartialOrd for StorePathHash {
- fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
- Some(self.cmp(other))
- }
-}
-
-#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
-pub struct StorePathName(String);
-
-impl StorePathName {
- pub fn new(s: &str) -> Result<Self, Error> {
- if s.is_empty() {
- return Err(Error::StorePathNameEmpty);
- }
-
- if s.len() > 211 {
- return Err(Error::StorePathNameTooLong);
- }
-
- let is_good_path_name = s.chars().all(|c| {
- c.is_ascii_alphabetic()
- || c.is_ascii_digit()
- || c == '+'
- || c == '-'
- || c == '.'
- || c == '_'
- || c == '?'
- || c == '='
- });
- if s.starts_with('.') || !is_good_path_name {
- return Err(Error::BadStorePathName);
- }
-
- Ok(Self(s.to_string()))
- }
-
- pub fn name(&self) -> &str {
- &self.0
- }
-}
-
-impl fmt::Display for StorePathName {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.write_str(&self.0)
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use assert_matches::assert_matches;
-
- #[test]
- fn test_parse() {
- let s = "7h7qgvs4kgzsn8a6rb273saxyqh4jxlz-konsole-18.12.3";
- let p = StorePath::new_from_base_name(&s).unwrap();
- assert_eq!(p.name.0, "konsole-18.12.3");
- assert_eq!(
- p.hash.0,
- [
- 0x9f, 0x76, 0x49, 0x20, 0xf6, 0x5d, 0xe9, 0x71, 0xc4, 0xca, 0x46, 0x21, 0xab, 0xff,
- 0x9b, 0x44, 0xef, 0x87, 0x0f, 0x3c
- ]
- );
- }
-
- #[test]
- fn test_no_name() {
- let s = "7h7qgvs4kgzsn8a6rb273saxyqh4jxlz-";
- assert_matches!(
- StorePath::new_from_base_name(&s),
- Err(Error::StorePathNameEmpty)
- );
- }
-
- #[test]
- fn test_no_dash() {
- let s = "7h7qgvs4kgzsn8a6rb273saxyqh4jxlz";
- assert_matches!(
- StorePath::new_from_base_name(&s),
- Err(Error::BadStorePath(_))
- );
- }
-
- #[test]
- fn test_short_hash() {
- let s = "7h7qgvs4kgzsn8a6rb273saxyqh4jxl-konsole-18.12.3";
- assert_matches!(
- StorePath::new_from_base_name(&s),
- Err(Error::BadStorePath(_))
- );
- }
-
- #[test]
- fn test_invalid_hash() {
- let s = "7h7qgvs4kgzsn8e6rb273saxyqh4jxlz-konsole-18.12.3";
- assert_matches!(StorePath::new_from_base_name(&s), Err(Error::BadBase32));
- }
-
- #[test]
- fn test_long_name() {
- let s = "7h7qgvs4kgzsn8a6rb273saxyqh4jxlz-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
- assert_matches!(StorePath::new_from_base_name(&s), Ok(_));
- }
-
- #[test]
- fn test_too_long_name() {
- let s = "7h7qgvs4kgzsn8a6rb273saxyqh4jxlz-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
- assert_matches!(
- StorePath::new_from_base_name(&s),
- Err(Error::StorePathNameTooLong)
- );
- }
-
- #[test]
- fn test_bad_name() {
- let s = "7h7qgvs4kgzsn8a6rb273saxyqh4jxlz-foo bar";
- assert_matches!(
- StorePath::new_from_base_name(&s),
- Err(Error::BadStorePathName)
- );
-
- let s = "7h7qgvs4kgzsn8a6rb273saxyqh4jxlz-kónsole";
- assert_matches!(
- StorePath::new_from_base_name(&s),
- Err(Error::BadStorePathName)
- );
- }
-
- #[test]
- fn test_roundtrip() {
- let s = "7h7qgvs4kgzsn8a6rb273saxyqh4jxlz-konsole-18.12.3";
- assert_eq!(StorePath::new_from_base_name(&s).unwrap().to_string(), s);
- }
-}