Skip to content

Commit affa2a5

Browse files
committed
feat: add index.threads configuration to gix::config::tree
1 parent 92e98b3 commit affa2a5

File tree

6 files changed

+104
-24
lines changed

6 files changed

+104
-24
lines changed

gix/src/config/tree/mod.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ pub(crate) mod root {
3838
pub const GITOXIDE: sections::Gitoxide = sections::Gitoxide;
3939
/// The `http` section.
4040
pub const HTTP: sections::Http = sections::Http;
41+
/// The `index` section.
42+
pub const INDEX: sections::Index = sections::Index;
4143
/// The `init` section.
4244
pub const INIT: sections::Init = sections::Init;
4345
/// The `pack` section.
@@ -69,6 +71,7 @@ pub(crate) mod root {
6971
&Self::EXTENSIONS,
7072
&Self::GITOXIDE,
7173
&Self::HTTP,
74+
&Self::INDEX,
7275
&Self::INIT,
7376
&Self::PACK,
7477
&Self::PROTOCOL,
@@ -84,9 +87,9 @@ pub(crate) mod root {
8487

8588
mod sections;
8689
pub use sections::{
87-
branch, checkout, core, credential, diff, extensions, gitoxide, http, protocol, remote, ssh, Author, Branch,
88-
Checkout, Clone, Committer, Core, Credential, Diff, Extensions, Gitoxide, Http, Init, Pack, Protocol, Remote, Safe,
89-
Ssh, Url, User,
90+
branch, checkout, core, credential, diff, extensions, gitoxide, http, index, protocol, remote, ssh, Author, Branch,
91+
Checkout, Clone, Committer, Core, Credential, Diff, Extensions, Gitoxide, Http, Index, Init, Pack, Protocol,
92+
Remote, Safe, Ssh, Url, User,
9093
};
9194

9295
/// Generic value implementations for static instantiation.

gix/src/config/tree/sections/index.rs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
use crate::{
2+
config,
3+
config::tree::{keys, Index, Key, Section},
4+
};
5+
6+
impl Index {
7+
/// The `index.threads` key.
8+
pub const THREADS: IndexThreads =
9+
IndexThreads::new_with_validate("threads", &config::Tree::INDEX, validate::IndexThreads);
10+
}
11+
12+
/// The `index.threads` key.
13+
pub type IndexThreads = keys::Any<validate::IndexThreads>;
14+
15+
mod index_threads {
16+
use crate::bstr::BStr;
17+
use crate::config;
18+
use crate::config::key::GenericErrorWithValue;
19+
use crate::config::tree::index::IndexThreads;
20+
use std::borrow::Cow;
21+
22+
impl IndexThreads {
23+
/// Parse `value` into the amount of threads to use, with `1` being single-threaded, or `0` indicating
24+
/// to select the amount of threads, with any other number being the specific amount of threads to use.
25+
pub fn try_into_index_threads(
26+
&'static self,
27+
value: Cow<'_, BStr>,
28+
) -> Result<usize, config::key::GenericErrorWithValue> {
29+
gix_config::Integer::try_from(value.as_ref())
30+
.ok()
31+
.and_then(|i| i.to_decimal().and_then(|i| i.try_into().ok()))
32+
.or_else(|| {
33+
gix_config::Boolean::try_from(value.as_ref())
34+
.ok()
35+
.map(|b| if b.0 { 0 } else { 1 })
36+
})
37+
.ok_or_else(|| GenericErrorWithValue::from_value(self, value.into_owned()))
38+
}
39+
}
40+
}
41+
42+
impl Section for Index {
43+
fn name(&self) -> &str {
44+
"index"
45+
}
46+
47+
fn keys(&self) -> &[&dyn Key] {
48+
&[&Self::THREADS]
49+
}
50+
}
51+
52+
mod validate {
53+
use crate::{bstr::BStr, config::tree::keys};
54+
55+
pub struct IndexThreads;
56+
impl keys::Validate for IndexThreads {
57+
fn validate(&self, value: &BStr) -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
58+
super::Index::THREADS.try_into_index_threads(value.into())?;
59+
Ok(())
60+
}
61+
}
62+
}

gix/src/config/tree/sections/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@ pub mod gitoxide;
5555
pub struct Http;
5656
pub mod http;
5757

58+
/// The `index` top-level section.
59+
#[derive(Copy, Clone, Default)]
60+
pub struct Index;
61+
pub mod index;
62+
5863
/// The `init` top-level section.
5964
#[derive(Copy, Clone, Default)]
6065
pub struct Init;

gix/src/repository/worktree.rs

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::config::cache::util::ApplyLeniencyDefault;
12
use crate::{worktree, Worktree};
23

34
/// Worktree iteration
@@ -58,23 +59,14 @@ impl crate::Repository {
5859
///
5960
/// It will use the `index.threads` configuration key to learn how many threads to use.
6061
/// Note that it may fail if there is no index.
61-
// TODO: test
6262
pub fn open_index(&self) -> Result<gix_index::File, worktree::open_index::Error> {
6363
let thread_limit = self
6464
.config
6565
.resolved
66-
.boolean("index", None, "threads")
67-
.map(|res| {
68-
res.map(|value| usize::from(!value)).or_else(|err| {
69-
gix_config::Integer::try_from(err.input.as_ref())
70-
.map_err(|err| worktree::open_index::Error::ConfigIndexThreads {
71-
value: err.input.clone(),
72-
err,
73-
})
74-
.map(|value| value.to_decimal().and_then(|v| v.try_into().ok()).unwrap_or(1))
75-
})
76-
})
77-
.transpose()?;
66+
.string("index", None, "threads")
67+
.map(|value| crate::config::tree::Index::THREADS.try_into_index_threads(value))
68+
.transpose()
69+
.with_lenient_default(self.config.lenient_config)?;
7870
gix_index::File::at(
7971
self.index_path(),
8072
self.object_hash(),

gix/src/worktree/mod.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -71,18 +71,12 @@ pub mod proxy;
7171

7272
///
7373
pub mod open_index {
74-
use crate::bstr::BString;
75-
7674
/// The error returned by [`Worktree::open_index()`][crate::Worktree::open_index()].
7775
#[derive(Debug, thiserror::Error)]
7876
#[allow(missing_docs)]
7977
pub enum Error {
80-
#[error("Could not interpret value '{}' as 'index.threads'", .value)]
81-
ConfigIndexThreads {
82-
value: BString,
83-
#[source]
84-
err: gix_config::value::Error,
85-
},
78+
#[error(transparent)]
79+
ConfigIndexThreads(#[from] crate::config::key::GenericErrorWithValue),
8680
#[error(transparent)]
8781
IndexFile(#[from] gix_index::file::init::Error),
8882
}

gix/tests/config/tree.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,30 @@ mod core {
351351
}
352352
}
353353

354+
mod index {
355+
use crate::config::tree::bcow;
356+
use gix::config::tree::{Index, Key};
357+
358+
#[test]
359+
fn threads() {
360+
for (value, expected) in [("false", 1), ("true", 0), ("0", 0), ("1", 1), ("2", 2), ("12", 12)] {
361+
assert_eq!(
362+
Index::THREADS.try_into_index_threads(bcow(value)).unwrap(),
363+
expected,
364+
"{value}"
365+
);
366+
assert!(Index::THREADS.validate(value.into()).is_ok());
367+
}
368+
assert_eq!(
369+
Index::THREADS
370+
.try_into_index_threads(bcow("nothing"))
371+
.unwrap_err()
372+
.to_string(),
373+
"The key \"index.threads=nothing\" was invalid"
374+
);
375+
}
376+
}
377+
354378
mod extensions {
355379
use gix::config::tree::{Extensions, Key};
356380

0 commit comments

Comments
 (0)