feat(snix/castore/PathComponent): add extension() method

This returns the file extension.

Change-Id: I488cbadbce027a37d53cee808bcf7a95283ed07d
Reviewed-on: https://cl.snix.dev/c/snix/+/30319
Tested-by: besadii
Reviewed-by: Domen Kožar <domen@cachix.org>
Reviewed-by: Stefan Junker <mail@stefanjunker.de>
This commit is contained in:
Florian Klink 2025-04-14 15:09:00 +02:00
parent 6b48bcc1bf
commit 8c525dcc2d

View file

@ -12,6 +12,18 @@ pub struct PathComponent {
pub(super) inner: bytes::Bytes, pub(super) inner: bytes::Bytes,
} }
impl PathComponent {
/// Extracts the extension (without leading dot) of a [PathComponent], if possible.
pub fn extension(&self) -> Option<&[u8]> {
let mut iter = self.inner[..].rsplitn(2, |b| *b == b'.');
let e = iter.next();
// Return None if there's no dot.
iter.next()?;
e
}
}
/// The maximum length an individual path component can have. /// The maximum length an individual path component can have.
/// Linux allows 255 bytes of actual name, so we pick that. /// Linux allows 255 bytes of actual name, so we pick that.
pub const MAX_NAME_LEN: usize = 255; pub const MAX_NAME_LEN: usize = 255;
@ -212,6 +224,15 @@ mod tests {
} }
} }
#[rstest]
#[case::without_dot(PathComponent { inner: "foo".into()}, None)]
#[case::simple(PathComponent { inner: "foo.txt".into()}, Some(&b"txt"[..]))]
#[case::empty(PathComponent { inner: "foo.".into()}, Some(&b""[..]))]
#[case::multiple(PathComponent { inner: "foo.bar.txt".into()}, Some(&b"txt"[..]))]
fn extension(#[case] p: PathComponent, #[case] exp_extension: Option<&[u8]>) {
assert_eq!(exp_extension, p.extension())
}
#[test] #[test]
fn error_toolong() { fn error_toolong() {
assert_eq!( assert_eq!(