Skip to content

Commit ccb607d

Browse files
committed
Merge branch 'iter'
2 parents 5fc379d + ff68295 commit ccb607d

File tree

4 files changed

+42
-16
lines changed

4 files changed

+42
-16
lines changed

Cargo.lock

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

gitoxide-core/Cargo.toml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ default = []
1818
## Discover all git repositories within a directory. Particularly useful with [skim](https://github.com/lotabout/skim).
1919
organize = ["dep:gix-url", "dep:jwalk"]
2020
## Derive the amount of time invested into a git repository akin to [git-hours](https://github.com/kimmobrunfeldt/git-hours).
21-
estimate-hours = ["dep:itertools", "dep:fs-err", "dep:crossbeam-channel", "dep:smallvec"]
21+
estimate-hours = ["dep:fs-err", "dep:crossbeam-channel", "dep:smallvec"]
2222
## Gather information about repositories and store it in a database for easy querying.
2323
query = ["dep:rusqlite"]
2424
## Run algorithms on a corpus of repositories and store their results for later comparison and intelligence gathering.
@@ -29,7 +29,7 @@ corpus = [ "dep:rusqlite", "dep:sysinfo", "organize", "dep:crossbeam-channel", "
2929
archive = ["dep:gix-archive-for-configuration-only", "gix/worktree-archive"]
3030

3131
## The ability to clean a repository, similar to `git clean`.
32-
clean = [ "gix/dirwalk" ]
32+
clean = ["gix/dirwalk"]
3333

3434
#! ### Mutually Exclusive Networking
3535
#! If both are set, _blocking-client_ will take precedence, allowing `--all-features` to be used.
@@ -72,7 +72,6 @@ gix-url = { version = "^0.27.0", path = "../gix-url", optional = true }
7272
jwalk = { version = "0.8.0", optional = true }
7373

7474
# for 'hours'
75-
itertools = { version = "0.12.0", optional = true }
7675
fs-err = { version = "2.6.0", optional = true }
7776
crossbeam-channel = { version = "0.5.6", optional = true }
7877
smallvec = { version = "1.10.0", optional = true }

gitoxide-core/src/hours/core.rs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ use std::{
77
};
88

99
use gix::bstr::BStr;
10-
use itertools::Itertools;
1110

1211
use crate::hours::{
1312
util::{add_lines, remove_lines},
@@ -25,17 +24,24 @@ pub fn estimate_hours(
2524
const MAX_COMMIT_DIFFERENCE_IN_MINUTES: f32 = 2.0 * MINUTES_PER_HOUR;
2625
const FIRST_COMMIT_ADDITION_IN_MINUTES: f32 = 2.0 * MINUTES_PER_HOUR;
2726

28-
let hours_for_commits = commits.iter().map(|t| &t.1).rev().tuple_windows().fold(
29-
0_f32,
30-
|hours, (cur, next): (&gix::actor::SignatureRef<'_>, &gix::actor::SignatureRef<'_>)| {
27+
let hours_for_commits = {
28+
let mut hours = 0.0;
29+
30+
let mut commits = commits.iter().map(|t| &t.1).rev();
31+
let mut cur = commits.next().expect("at least one commit if we are here");
32+
33+
for next in commits {
3134
let change_in_minutes = (next.time.seconds.saturating_sub(cur.time.seconds)) as f32 / MINUTES_PER_HOUR;
3235
if change_in_minutes < MAX_COMMIT_DIFFERENCE_IN_MINUTES {
33-
hours + change_in_minutes / MINUTES_PER_HOUR
36+
hours += change_in_minutes / MINUTES_PER_HOUR
3437
} else {
35-
hours + (FIRST_COMMIT_ADDITION_IN_MINUTES / MINUTES_PER_HOUR)
38+
hours += FIRST_COMMIT_ADDITION_IN_MINUTES / MINUTES_PER_HOUR
3639
}
37-
},
38-
);
40+
cur = next;
41+
}
42+
43+
hours
44+
};
3945

4046
let author = &commits[0].1;
4147
let (files, lines) = (!stats.is_empty())

gitoxide-core/src/hours/util.rs

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use std::sync::atomic::{AtomicUsize, Ordering};
22

33
use gix::bstr::{BStr, ByteSlice};
4-
use itertools::Itertools;
54

65
use crate::hours::core::HOURS_PER_WORKDAY;
76

@@ -43,6 +42,29 @@ impl<'a> From<&'a WorkByEmail> for WorkByPerson {
4342
}
4443
}
4544

45+
fn join<I>(mut iter: I, sep: &str) -> String
46+
where
47+
I: Iterator,
48+
<I as Iterator>::Item: std::fmt::Display,
49+
{
50+
use ::std::fmt::Write;
51+
52+
match iter.next() {
53+
None => String::new(),
54+
Some(first_elt) => {
55+
// estimate lower bound of capacity needed
56+
let (lower, _) = iter.size_hint();
57+
let mut result = String::with_capacity(sep.len() * lower);
58+
write!(&mut result, "{first_elt}").expect("enough memory");
59+
iter.for_each(|elt| {
60+
result.push_str(sep);
61+
write!(&mut result, "{elt}").expect("enough memory");
62+
});
63+
result
64+
}
65+
}
66+
}
67+
4668
impl WorkByPerson {
4769
pub fn write_to(
4870
&self,
@@ -53,9 +75,9 @@ impl WorkByPerson {
5375
) -> std::io::Result<()> {
5476
writeln!(
5577
out,
56-
"{} <{}>",
57-
self.name.iter().join(", "),
58-
self.email.iter().join(", ")
78+
"{names} <{mails}>",
79+
names = join(self.name.iter(), ", "),
80+
mails = join(self.email.iter(), ", ")
5981
)?;
6082
writeln!(out, "{} commits found", self.num_commits)?;
6183
writeln!(

0 commit comments

Comments
 (0)