Skip to content

Commit d29a179

Browse files
committed
Use gix_fs::stack::ToNormalPathComponents everywhere.
1 parent 569c186 commit d29a179

File tree

10 files changed

+57
-28
lines changed

10 files changed

+57
-28
lines changed

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

gitoxide-core/src/repository/attributes/query.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ pub struct Options {
88
}
99

1010
pub(crate) mod function {
11-
use std::{borrow::Cow, io, path::Path};
12-
1311
use anyhow::bail;
1412
use gix::bstr::BStr;
13+
use std::borrow::Cow;
14+
use std::{io, path::Path};
1515

1616
use crate::{
1717
is_dir_to_mode,
@@ -44,7 +44,7 @@ pub(crate) mod function {
4444
.ok()
4545
.map(|m| is_dir_to_mode(m.is_dir()));
4646

47-
let entry = cache.at_entry(path.as_slice(), mode)?;
47+
let entry = cache.at_entry(&path, mode)?;
4848
if !entry.matching_attributes(&mut matches) {
4949
continue;
5050
}

gitoxide-core/src/repository/exclude.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ pub fn query(
4848
.metadata()
4949
.ok()
5050
.map(|m| is_dir_to_mode(m.is_dir()));
51-
let entry = cache.at_entry(path.as_slice(), mode)?;
51+
let entry = cache.at_entry(&path, mode)?;
5252
let match_ = entry
5353
.matching_exclude_pattern()
5454
.and_then(|m| (show_ignore_patterns || !m.pattern.is_negative()).then_some(m));

gix-fs/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ doctest = false
1919
serde = ["dep:serde"]
2020

2121
[dependencies]
22+
bstr = "1.5.0"
23+
gix-path = { version = "^0.10.14", path = "../gix-path" }
2224
gix-features = { version = "^0.40.0", path = "../gix-features", features = ["fs-read-dir"] }
2325
gix-utils = { version = "^0.1.14", path = "../gix-utils" }
2426
thiserror = "2.0.0"

gix-fs/src/stack.rs

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1+
use crate::Stack;
2+
use bstr::{BStr, BString, ByteSlice};
13
use std::ffi::OsStr;
24
use std::path::{Component, Path, PathBuf};
35

4-
use crate::Stack;
5-
66
///
77
pub mod to_normal_path_components {
88
use std::ffi::OsString;
@@ -13,6 +13,8 @@ pub mod to_normal_path_components {
1313
pub enum Error {
1414
#[error("Input path \"{path}\" contains relative or absolute components", path = std::path::Path::new(.0.as_os_str()).display())]
1515
NotANormalComponent(OsString),
16+
#[error("Could not convert to UTF8 or from UTF8 due to ill-formed input")]
17+
IllegalUtf8,
1618
}
1719
}
1820

@@ -33,6 +35,36 @@ impl ToNormalPathComponents for &Path {
3335
}
3436
}
3537

38+
impl ToNormalPathComponents for &BStr {
39+
fn to_normal_path_components(&self) -> impl Iterator<Item = Result<&OsStr, to_normal_path_components::Error>> {
40+
self.split(|b| *b == b'/').map(|component| {
41+
gix_path::try_from_byte_slice(component.as_bstr())
42+
.map_err(|_| to_normal_path_components::Error::IllegalUtf8)
43+
.map(|p| p.as_os_str())
44+
})
45+
}
46+
}
47+
48+
impl ToNormalPathComponents for &str {
49+
fn to_normal_path_components(&self) -> impl Iterator<Item = Result<&OsStr, to_normal_path_components::Error>> {
50+
self.split('/').map(|component| {
51+
gix_path::try_from_byte_slice(component.as_bytes())
52+
.map_err(|_| to_normal_path_components::Error::IllegalUtf8)
53+
.map(|p| p.as_os_str())
54+
})
55+
}
56+
}
57+
58+
impl ToNormalPathComponents for &BString {
59+
fn to_normal_path_components(&self) -> impl Iterator<Item = Result<&OsStr, to_normal_path_components::Error>> {
60+
self.split(|b| *b == b'/').map(|component| {
61+
gix_path::try_from_byte_slice(component.as_bstr())
62+
.map_err(|_| to_normal_path_components::Error::IllegalUtf8)
63+
.map(|p| p.as_os_str())
64+
})
65+
}
66+
}
67+
3668
/// Access
3769
impl Stack {
3870
/// Returns the top-level path of the stack.

gix-status/src/stack.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1+
use crate::SymlinkCheck;
12
use bstr::BStr;
3+
use gix_fs::stack::ToNormalPathComponents;
24
use gix_fs::Stack;
35
use std::borrow::Cow;
46
use std::path::{Path, PathBuf};
57

6-
use crate::SymlinkCheck;
7-
88
impl SymlinkCheck {
99
/// Create a new stack that starts operating at `root`.
1010
pub fn new(root: PathBuf) -> Self {
@@ -24,7 +24,7 @@ impl SymlinkCheck {
2424
/// ### Note
2525
///
2626
/// On windows, no verification is performed, instead only the combined path is provided as usual.
27-
pub fn verified_path(&mut self, relative_path: &Path) -> std::io::Result<&Path> {
27+
pub fn verified_path(&mut self, relative_path: impl ToNormalPathComponents) -> std::io::Result<&Path> {
2828
self.inner.make_relative_path_current(relative_path, &mut Delegate)?;
2929
Ok(self.inner.current())
3030
}
@@ -34,7 +34,7 @@ impl SymlinkCheck {
3434
/// For convenience, this incarnation is tuned to be easy to use with Git paths, i.e. slash-separated `BString` path.
3535
pub fn verified_path_allow_nonexisting(&mut self, relative_path: &BStr) -> std::io::Result<Cow<'_, Path>> {
3636
let rela_path = gix_path::try_from_bstr(relative_path).map_err(std::io::Error::other)?;
37-
if let Err(err) = self.verified_path(&rela_path) {
37+
if let Err(err) = self.verified_path(rela_path.as_ref()) {
3838
if err.kind() == std::io::ErrorKind::NotFound {
3939
Ok(Cow::Owned(self.inner.root().join(rela_path)))
4040
} else {

gix-worktree-state/src/checkout/entry.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ where
8080
let dest_relative = gix_path::try_from_bstr(entry_path).map_err(|_| crate::checkout::Error::IllformedUtf8 {
8181
path: entry_path.to_owned(),
8282
})?;
83-
let path_cache = path_cache.at_path(dest_relative, Some(entry.mode), &*objects)?;
83+
let path_cache = path_cache.at_path(dest_relative.as_ref(), Some(entry.mode), &*objects)?;
8484
let dest = path_cache.path();
8585

8686
let object_size = match entry.mode {

gix-worktree/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ description = "A crate of the gitoxide project for shared worktree related types
99
authors = ["Sebastian Thiel <sebastian.thiel@icloud.com>"]
1010
edition = "2021"
1111
include = ["src/**/*", "LICENSE-*"]
12-
rust-version = "1.70"
12+
rust-version = "1.74"
1313
autotests = false
1414

1515
[lib]

gix-worktree/src/stack/mod.rs

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ impl Stack {
113113
/// Provide access to cached information for that `relative` path via the returned platform.
114114
pub fn at_path(
115115
&mut self,
116-
relative: impl AsRef<Path>,
116+
relative: impl ToNormalPathComponents,
117117
mode: Option<gix_index::entry::Mode>,
118118
objects: &dyn gix_object::Find,
119119
) -> std::io::Result<Platform<'_>> {
@@ -127,8 +127,7 @@ impl Stack {
127127
case: self.case,
128128
statistics: &mut self.statistics,
129129
};
130-
self.stack
131-
.make_relative_path_current(relative.as_ref(), &mut delegate)?;
130+
self.stack.make_relative_path_current(relative, &mut delegate)?;
132131
Ok(Platform {
133132
parent: self,
134133
is_dir: mode_is_dir(mode),
@@ -148,15 +147,8 @@ impl Stack {
148147
objects: &dyn gix_object::Find,
149148
) -> std::io::Result<Platform<'_>> {
150149
let relative = relative.into();
151-
let relative_path = gix_path::try_from_bstr(relative).map_err(|_err| {
152-
std::io::Error::new(
153-
std::io::ErrorKind::Other,
154-
format!("The path \"{relative}\" contained invalid UTF-8 and could not be turned into a path"),
155-
)
156-
})?;
157-
158150
self.at_path(
159-
relative_path,
151+
relative,
160152
mode.or_else(|| relative.ends_with_str("/").then_some(gix_index::entry::Mode::DIR)),
161153
objects,
162154
)
@@ -210,6 +202,7 @@ impl Stack {
210202
///
211203
pub mod delegate;
212204
use delegate::StackDelegate;
205+
use gix_fs::stack::ToNormalPathComponents;
213206

214207
mod platform;
215208
///

gix/src/attribute_stack.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1+
use crate::{types::AttributeStack, Repository};
2+
use gix_fs::stack::ToNormalPathComponents;
13
use std::ops::{Deref, DerefMut};
24

3-
use crate::{bstr::BStr, types::AttributeStack, Repository};
4-
55
/// Lifecycle
66
impl<'repo> AttributeStack<'repo> {
77
/// Create a new instance from a `repo` and the underlying pre-configured `stack`.
@@ -44,7 +44,7 @@ impl AttributeStack<'_> {
4444
relative: impl AsRef<std::path::Path>,
4545
mode: Option<gix_index::entry::Mode>,
4646
) -> std::io::Result<gix_worktree::stack::Platform<'_>> {
47-
self.inner.at_path(relative, mode, &self.repo.objects)
47+
self.inner.at_path(relative.as_ref(), mode, &self.repo.objects)
4848
}
4949

5050
/// Obtain a platform for attribute or ignore lookups from a repo-`relative` path, typically obtained from an index entry.
@@ -53,9 +53,9 @@ impl AttributeStack<'_> {
5353
/// If `relative` ends with `/` and `mode` is `None`, it is automatically assumed to be a directory.
5454
pub fn at_entry<'r>(
5555
&mut self,
56-
relative: impl Into<&'r BStr>,
56+
relative: impl ToNormalPathComponents,
5757
mode: Option<gix_index::entry::Mode>,
5858
) -> std::io::Result<gix_worktree::stack::Platform<'_>> {
59-
self.inner.at_entry(relative, mode, &self.repo.objects)
59+
self.inner.at_path(relative, mode, &self.repo.objects)
6060
}
6161
}

0 commit comments

Comments
 (0)