1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
use std::fmt::{self, Write};
pub fn join<I: Iterator>(items: I) -> JoinBuilder<'static, I> {
JoinBuilder {
items,
prefix: "",
suffix: "",
sep: ", ",
}
}
pub struct JoinBuilder<'a, I> {
items: I,
prefix: &'a str,
suffix: &'a str,
sep: &'a str,
}
impl<'a, I> JoinBuilder<'a, I> {
pub fn prefix(self, prefix: &'a str) -> Self {
JoinBuilder { prefix, .. self }
}
pub fn suffix(self, suffix: &'a str) -> Self {
JoinBuilder { suffix, .. self }
}
pub fn surround_with(self, prefix: &'a str, suffix: &'a str) -> Self {
self.prefix(prefix).suffix(suffix)
}
pub fn separator(self, sep: &'a str) -> Self {
JoinBuilder { sep, .. self }
}
}
impl<'a, I> JoinBuilder<'a, I>
where
I: Iterator,
I::Item: ToBuf
{
pub fn to_buf(self, buf: &mut String) {
buf.push_str(self.prefix);
let mut first = true;
for item in self.items {
if !first {
buf.push_str(self.sep);
}
first = false;
item.to_buf(buf);
}
buf.push_str(self.suffix);
}
pub fn to_string(self) -> String {
let cap =
self.prefix.len()
+ self.suffix.len()
+ self.items.size_hint().0 * self.sep.len();
let mut buf = String::with_capacity(cap);
self.to_buf(&mut buf);
buf
}
}
pub trait ToBuf {
fn to_buf(&self, buf: &mut String);
}
impl<T: fmt::Display> ToBuf for T {
fn to_buf(&self, buf: &mut String) {
write!(buf, "{}", self)
.unwrap()
}
}