synthphonia/utils/join.rs
1use ext_trait::extension;
2
3
4/// This structure wraps an iterator alongside a separator string to facilitate joining elements with a specified delimiter during formatting.
5///
6///
7/// It holds a cloneable iterator over items and a string slice that serves as the separator between the items when they are formatted.
8/// This design supports multiple passes of the iterator during formatting operations and enables implementations of formatting traits to output the joined elements either using their debug or display representations.
9pub struct FmtJoin<'i, T: Iterator<Item=I> + Clone, I>(T, &'i str);
10
11impl<'i, T: Iterator<Item=I> + Clone, I: std::fmt::Debug> std::fmt::Debug for FmtJoin<'i, T, I> {
12 /// Formats a sequence of items by concatenating their Debug representations with a specified separator.
13 /// This function takes a formatter and writes the Debug form of the first element, then iterates over the remaining items, prefixing each with the provided separator before writing their Debug representations.
14 ///
15 /// It clones the underlying iterator, ensuring the original sequence is preserved, and gracefully handles cases where the iterator may be empty by simply returning a successful formatting result.
16 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17 let mut iter = self.0.clone();
18 if let Some(a) = iter.next() {
19 write!(f, "{:?}", a)?;
20 for p in iter {
21 write!(f, "{}{:?}", self.1, p)?;
22 }
23 }
24 Ok(())
25 }
26}
27
28impl<'i, T: Iterator<Item=I> + Clone, I: std::fmt::Display> std::fmt::Display for FmtJoin<'i, T, I> {
29 /// Formats and writes the joined representation of iterator elements with a given separator.
30 ///
31 ///
32 /// Writes the first element without a preceding separator and then appends each subsequent element prefixed by the specified separator by iterating over a cloned version of the stored iterator, thereby yielding a formatted string representation.
33 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34 let mut iter = self.0.clone();
35 if let Some(a) = iter.next() {
36 write!(f, "{}", a)?;
37 for p in iter {
38 write!(f, "{}{}", self.1, p)?;
39 }
40 }
41 Ok(())
42 }
43}
44
45
46#[extension(pub trait FmtJoinIter)]
47impl<T: Iterator + Clone> T {
48 /// Creates a join formatter for an iterator.
49 /// This method consumes the iterator, associates it with a given separator string, and returns a wrapper that, when formatted, joins the elements of the iterator using the provided separator.
50 fn fmtjoin<'i>(self, sep: &'i str) -> FmtJoin<'i, T, T::Item> {
51 FmtJoin(self, sep)
52 }
53}