diff options
author | edef <edef@edef.eu> | 2024-05-01T12·02+0000 |
---|---|---|
committer | edef <edef@edef.eu> | 2024-05-01T13·40+0000 |
commit | 1bb023df91640268fad1e74571b5dc94822a79b3 (patch) | |
tree | 24fdfbe0bddafc6c7af4dea409d0c56ccf78e541 | |
parent | aa53338ddbcf6a7c0173789c78608df50839e15b (diff) |
feat(tvix/castore/path): single-component paths are children of ROOT r/8058
The empty path (Path::ROOT) is explicitly a valid path, and "foo" is simply a child of "". The root itself is the only path without a parent. Change-Id: Iff00dc8aed89eaf98702b664c0df658bd5a1d88a Reviewed-on: https://cl.tvl.fyi/c/depot/+/11569 Reviewed-by: flokli <flokli@flokli.de> Tested-by: BuildkiteCI
-rw-r--r-- | tvix/castore/src/path.rs | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/tvix/castore/src/path.rs b/tvix/castore/src/path.rs index dfbf92232557..d2b011947a87 100644 --- a/tvix/castore/src/path.rs +++ b/tvix/castore/src/path.rs @@ -46,11 +46,25 @@ impl Path { Some(unsafe { Path::from_bytes_unchecked(bytes) }) } + /// Returns the path without its final component, if there is one. + /// + /// Note that the parent of a bare file name is [Path::ROOT]. + /// [Path::ROOT] is the only path without a parent. pub fn parent(&self) -> Option<&Path> { - let (parent, _file_name) = self.inner.rsplit_once_str(b"/")?; + // The root does not have a parent. + if self.inner.is_empty() { + return None; + } - // SAFETY: The parent of a valid Path is a valid Path. - Some(unsafe { Path::from_bytes_unchecked(parent) }) + Some( + if let Some((parent, _file_name)) = self.inner.rsplit_once_str(b"/") { + // SAFETY: The parent of a valid Path is a valid Path. + unsafe { Path::from_bytes_unchecked(parent) } + } else { + // The parent of a bare file name is the root. + Path::ROOT + }, + ) } pub fn join(&self, name: &[u8]) -> Result<PathBuf, std::io::Error> { @@ -166,7 +180,7 @@ impl Display for PathBuf { #[cfg(test)] mod test { - use super::PathBuf; + use super::{Path, PathBuf}; use bstr::ByteSlice; use rstest::rstest; @@ -214,6 +228,7 @@ mod test { } #[rstest] + #[case("foo", "")] #[case("foo/bar", "foo")] #[case("foo2/bar2", "foo2")] #[case("foo/bar/baz", "foo/bar")] @@ -222,13 +237,8 @@ mod test { } #[rstest] - #[case::empty("")] - #[case::single("foo")] - pub fn no_parent(#[case] p: PathBuf) { - assert!(p.parent().is_none()); - - // same for Path - assert!(p.as_ref().parent().is_none()); + pub fn no_parent() { + assert!(Path::ROOT.parent().is_none()); } #[rstest] |