1pub use crate::as_ref::Join;
45
46pub mod display {
48 pub trait Join {
50
51 fn write_join<I: Display, W: Write, T: IntoIterator<Item=I>>(&self, writer: W, coll: T) -> io::Result<usize>;
54
55 fn join<I: Display, T: IntoIterator<Item=I>>(&self, coll: T) -> String {
58 let mut s = Vec::new();
59 self.write_join(&mut s, coll).expect("This shouldn't fail");
61 String::from_utf8(s).unwrap()
64 }
65 }
66
67 impl<A: AsRef<str>> Join for A {
68 fn write_join<I: Display, W: Write, T: IntoIterator<Item=I>>(&self, mut writer: W, coll: T) -> io::Result<usize> {
69 let mut iter = coll.into_iter();
70 let mut written = 0;
71 if let Some(first) = iter.next() {
72 let first = first.to_string();
73 let bytes = first.as_bytes();
74 writer.write_all(bytes)?;
75 written += bytes.len();
76 }
77 for s in iter {
78 let t1 = self.as_ref().as_bytes();
79 writer.write_all(t1)?;
80 written += t1.len();
81
82 let s = s.to_string();
83 let t2 = s.as_bytes();
84 writer.write_all(t2)?;
85 written += t2.len();
86 }
87 writer.flush()?;
88 io::Result::Ok(written)
89 }
90 }
91
92 #[cfg(test)]
93 mod tests {
94 #[test]
95 fn write_join_to_file() {
96 let v = vec![];
97 let mut cur = Cursor::new(v);
98 let written = "=".write_join(&mut cur, &['a', 'b', 'c']).expect("Couldn't write joined string");
99 let result = cur.into_inner();
100 assert_eq!(written, 5);
101 assert_eq!(&result[..], "a=b=c".as_bytes());
102 }
103
104 #[test]
105 fn join_with_heap_string() {
106 let equal = String::from("=");
107 let result = equal.join(&['a', 'b', 'c']);
108 assert_eq!("a=b=c", &result[..]);
109 }
110
111 #[test]
112 fn join_with_borrowed_string() {
113 let equal = String::from("=");
114 let eq = &equal[..];
115 let result = eq.join(&['a', 'b', 'c']);
116 assert_eq!("a=b=c", &result[..]);
117 }
118
119 #[test]
120 fn join_with_cow_string() {
121 let equal = String::from("=");
122 let eq: Cow<'_, str> = Cow::Borrowed(&equal[..]);
123 let result = eq.join(&['a', 'b', 'c']);
124 assert_eq!("a=b=c", &result[..]);
125 }
126
127 #[test]
128 fn join_hashset() {
129 let set = {
130 let mut set = HashSet::new();
131 set.insert('a');
132 set.insert('b');
133 set.insert('c');
134 set
135 };
136 let result = "=".join(&set);
137 assert!(vec!["a=b=c", "a=c=b", "b=a=c", "b=c=a", "c=a=b", "c=b=a"].contains(&&result[..]));
138 }
139
140 use std::io::Cursor;
141 use std::borrow::Cow;
142 use std::collections::HashSet;
143 use super::Join;
144 }
145
146 use std::{
147 fmt::Display,
148 io::{self, Write},
149 };
150}
151
152pub mod as_ref {
154
155 pub trait Join {
157
158 fn write_join<I: AsRef<str>, W: Write, T: IntoIterator<Item=I>>(&self, writer: W, coll: T) -> io::Result<usize>;
161
162 fn join<I: AsRef<str>, T: IntoIterator<Item=I>>(&self, coll: T) -> String {
165 let mut s = Vec::new();
166 self.write_join(&mut s, coll).expect("This shouldn't fail");
168 String::from_utf8(s).unwrap()
171 }
172 }
173
174 impl<A: AsRef<str>> Join for A {
175 fn write_join<I: AsRef<str>, W: Write, T: IntoIterator<Item=I>>(&self, mut writer: W, coll: T) -> io::Result<usize> {
176 let mut iter = coll.into_iter();
177 let mut written = 0;
178 if let Some(first) = iter.next() {
179 let bytes = first.as_ref().as_bytes();
180 writer.write_all(bytes)?;
181 written += bytes.len();
182 }
183 for s in iter {
184 let t1 = self.as_ref().as_bytes();
185 writer.write_all(t1)?;
186 written += t1.len();
187
188 let t2 = s.as_ref().as_bytes();
189 writer.write_all(t2)?;
190 written += t2.len();
191 }
192 writer.flush()?;
193 io::Result::Ok(written)
194 }
195 }
196
197 #[cfg(test)]
198 mod tests {
199 #[test]
200 fn write_join_to_file() {
201 let v = vec![];
202 let mut cur = Cursor::new(v);
203 let written = "=".write_join(&mut cur, &["a", "b", "c"]).expect("Couldn't write joined string");
204 let result = cur.into_inner();
205 assert_eq!(written, 5);
206 assert_eq!(&result[..], "a=b=c".as_bytes());
207 }
208
209 #[test]
210 fn join_with_heap_string() {
211 let equal = String::from("=");
212 let result = equal.join(&["a", "b", "c"]);
213 assert_eq!("a=b=c", &result[..]);
214 }
215
216 #[test]
217 fn join_with_borrowed_string() {
218 let equal = String::from("=");
219 let eq = &equal[..];
220 let result = eq.join(&["a", "b", "c"]);
221 assert_eq!("a=b=c", &result[..]);
222 }
223
224 #[test]
225 fn join_with_cow_string() {
226 let equal = String::from("=");
227 let eq: Cow<'_, str> = Cow::Borrowed(&equal[..]);
228 let result = eq.join(&["a", "b", "c"]);
229 assert_eq!("a=b=c", &result[..]);
230 }
231
232 #[test]
233 fn join_hashset() {
234 let set = {
235 let mut set = HashSet::new();
236 set.insert("a");
237 set.insert("b");
238 set.insert("c");
239 set
240 };
241 let result = "=".join(&set);
242 assert!(vec!["a=b=c", "a=c=b", "b=a=c", "b=c=a", "c=a=b", "c=b=a"].contains(&&result[..]));
243 }
244
245 use std::io::Cursor;
246 use std::borrow::Cow;
247 use std::collections::HashSet;
248 use super::Join;
249 }
250
251 use std::{
252 io::{self, Write},
253 };
254}