Skip to content

Commit a4ac58e

Browse files
committed
user itertools join to avoid allocations
1 parent 5ddbe72 commit a4ac58e

File tree

1 file changed

+25
-16
lines changed

1 file changed

+25
-16
lines changed

gitoxide-core/src/hours/util.rs

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,29 @@ impl<'a> From<&'a WorkByEmail> for WorkByPerson {
4242
}
4343
}
4444

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}").unwrap();
59+
iter.for_each(|elt| {
60+
result.push_str(sep);
61+
write!(&mut result, "{elt}").unwrap();
62+
});
63+
result
64+
}
65+
}
66+
}
67+
4568
impl WorkByPerson {
4669
pub fn write_to(
4770
&self,
@@ -53,22 +76,8 @@ impl WorkByPerson {
5376
writeln!(
5477
out,
5578
"{names} <{mails}>",
56-
names = self
57-
.name
58-
.iter()
59-
// BStr does not impl slice::Join
60-
.map(|s| s.to_string())
61-
.collect::<Vec<_>>()
62-
.as_slice()
63-
.join(", "),
64-
mails = self
65-
.email
66-
.iter()
67-
// BStr does not impl slice::Join
68-
.map(|s| s.to_string())
69-
.collect::<Vec<_>>()
70-
.as_slice()
71-
.join(", ")
79+
names = join(self.name.iter(), ", "),
80+
mails = join(self.email.iter(), ", ")
7281
)?;
7382
writeln!(out, "{} commits found", self.num_commits)?;
7483
writeln!(

0 commit comments

Comments
 (0)