feat(tvix/castore/path): single-component paths are children of ROOT
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
This commit is contained in:
		
							parent
							
								
									aa53338ddb
								
							
						
					
					
						commit
						1bb023df91
					
				
					 1 changed files with 21 additions and 11 deletions
				
			
		| 
						 | 
					@ -46,11 +46,25 @@ impl Path {
 | 
				
			||||||
        Some(unsafe { Path::from_bytes_unchecked(bytes) })
 | 
					        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> {
 | 
					    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;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Some(
 | 
				
			||||||
 | 
					            if let Some((parent, _file_name)) = self.inner.rsplit_once_str(b"/") {
 | 
				
			||||||
                // SAFETY: The parent of a valid Path is a valid Path.
 | 
					                // SAFETY: The parent of a valid Path is a valid Path.
 | 
				
			||||||
        Some(unsafe { Path::from_bytes_unchecked(parent) })
 | 
					                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> {
 | 
					    pub fn join(&self, name: &[u8]) -> Result<PathBuf, std::io::Error> {
 | 
				
			||||||
| 
						 | 
					@ -166,7 +180,7 @@ impl Display for PathBuf {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[cfg(test)]
 | 
					#[cfg(test)]
 | 
				
			||||||
mod test {
 | 
					mod test {
 | 
				
			||||||
    use super::PathBuf;
 | 
					    use super::{Path, PathBuf};
 | 
				
			||||||
    use bstr::ByteSlice;
 | 
					    use bstr::ByteSlice;
 | 
				
			||||||
    use rstest::rstest;
 | 
					    use rstest::rstest;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -214,6 +228,7 @@ mod test {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[rstest]
 | 
					    #[rstest]
 | 
				
			||||||
 | 
					    #[case("foo", "")]
 | 
				
			||||||
    #[case("foo/bar", "foo")]
 | 
					    #[case("foo/bar", "foo")]
 | 
				
			||||||
    #[case("foo2/bar2", "foo2")]
 | 
					    #[case("foo2/bar2", "foo2")]
 | 
				
			||||||
    #[case("foo/bar/baz", "foo/bar")]
 | 
					    #[case("foo/bar/baz", "foo/bar")]
 | 
				
			||||||
| 
						 | 
					@ -222,13 +237,8 @@ mod test {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[rstest]
 | 
					    #[rstest]
 | 
				
			||||||
    #[case::empty("")]
 | 
					    pub fn no_parent() {
 | 
				
			||||||
    #[case::single("foo")]
 | 
					        assert!(Path::ROOT.parent().is_none());
 | 
				
			||||||
    pub fn no_parent(#[case] p: PathBuf) {
 | 
					 | 
				
			||||||
        assert!(p.parent().is_none());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // same for Path
 | 
					 | 
				
			||||||
        assert!(p.as_ref().parent().is_none());
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[rstest]
 | 
					    #[rstest]
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue