1use core::{
4 fmt::{Display, Formatter, Result},
5 marker::PhantomData,
6 slice::Iter,
7};
8
9pub trait Iterable<Item> {
11 fn iter<'i>(&'i self) -> Iter<'i, Item>;
13}
14
15pub trait AsItemFormatter<'c, I>: AsRef<[I]> + Sized
17where
18 I: 'c,
19{
20 fn as_item_formatter<S, F>(&'c self, separator: S, fmt: F) -> ItemFormatter<'c, Self, I, F>
22 where
23 S: ToString,
24 F: Fn(&mut Formatter<'_>, &'c I) -> Result,
25 {
26 ItemFormatter::new(self, separator, fmt)
27 }
28}
29
30impl<Item, Collection> Iterable<Item> for Collection
31where
32 Collection: AsRef<[Item]>,
33{
34 fn iter<'i>(&'i self) -> Iter<'i, Item> {
35 self.as_ref().iter()
36 }
37}
38
39impl<'c, I, C> AsItemFormatter<'c, I> for C
40where
41 I: 'c,
42 C: AsRef<[I]> + Sized,
43{
44}
45
46pub struct ItemFormatter<'c, C, I, F>
48where
49 C: Iterable<I>,
50 I: 'c,
51 F: Fn(&mut Formatter<'_>, &'c I) -> Result,
52{
53 fmt: F,
55 items: &'c C,
57 separator: String,
59 item: PhantomData<I>,
61}
62impl<'c, C, I, F> ItemFormatter<'c, C, I, F>
63where
64 C: Iterable<I>,
65 I: 'c,
66 F: Fn(&mut Formatter<'_>, &'c I) -> Result,
67{
68 pub fn new<S: ToString>(collection: &'c C, separator: S, fmt: F) -> Self {
70 Self {
71 fmt,
72 items: collection,
73 separator: separator.to_string(),
74 item: PhantomData,
75 }
76 }
77}
78
79impl<'c, C, I, F> Display for ItemFormatter<'c, C, I, F>
80where
81 C: Iterable<I>,
82 I: 'c,
83 F: Fn(&mut Formatter<'_>, &'c I) -> Result,
84{
85 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
86 write!(f, "[")?;
87
88 let iter = self.items.iter();
89 let length = iter.len();
90 for (index, item) in iter.enumerate() {
91 (self.fmt)(f, item)?;
92 if !self.separator.is_empty() && index < length - 1 {
93 write!(f, "{}", self.separator)?;
94 }
95 }
96
97 write!(f, "]")?;
98 Ok(())
99 }
100}
101
102#[cfg(test)]
103mod test {
104 use crate::item_formatter::AsItemFormatter;
105
106 #[test]
107 fn test() {
108 let items = (0..128).collect::<Vec<_>>();
109
110 println!(
111 "{}",
112 items.as_item_formatter(", ", |f, item| write!(f, "0x{item:02x}"))
113 );
114 }
115}