macro_toolset/string/general/
iterator.rs

1//! Implementations for any `Iterator`.
2//!
3//! # Concepts
4//!
5//! Items of the iterator must implement `StringT` and are all considered
6//! **independent** (like what we do for tuple, hmmm, tuple with fixed length
7//! and with items that are all with the same type?).
8//!
9//! Since the compiler will complain that *upstream crates may add a new impl
10//! of trait [`std::iter::Iterator`] for type `{I}`*, we cannot simply implement
11//! `StringT` for `T` where `T`: `{Trait}` but concrete one instead.
12//!
13//! This crate has already implemented `StringT` for the following types:
14//!
15//! - [`std::iter::Map`]
16//!
17//! For array-or-slice-like types:
18//!
19//! - `Vec<T>`
20//! - `[T; N]`
21//! - `&[T]` or `&[T; N]`
22//!
23//!   Only when &T implements `StringT`.
24//!   We have implemented `StringT` for most `&T` where T: Copy, though best
25//!   effort.
26
27use super::{StringExtT, StringT};
28use crate::wrapper;
29
30wrapper! {
31    #[derive(Debug)]
32    /// Wrapper for any iterator with items implementing `StringT`.
33
34    pub IterWrapper<I>(pub I)
35}
36
37#[macro_export]
38/// See [`IterWrapper`].
39macro_rules! str_iter_wrapper {
40    ($inner:expr) => {
41        $crate::string::general::iterator::IterWrapper { inner: $inner }
42    };
43}
44
45impl<I> StringT for IterWrapper<I>
46where
47    I: Iterator,
48    I::Item: StringT,
49{
50    #[inline]
51    fn encode_to_buf(self, string: &mut Vec<u8>) {
52        for item in self.inner {
53            item.encode_to_buf(string);
54        }
55    }
56
57    #[inline]
58    fn encode_to_buf_with_separator(self, string: &mut Vec<u8>, separator: &str) {
59        for item in self.inner {
60            item.encode_to_buf_with_separator(string, separator);
61        }
62    }
63
64    #[inline]
65    fn encode_to_bytes_buf(self, string: &mut bytes::BytesMut) {
66        for item in self.inner {
67            item.encode_to_bytes_buf(string);
68        }
69    }
70
71    #[inline]
72    fn encode_to_bytes_buf_with_separator(self, string: &mut bytes::BytesMut, separator: &str) {
73        for item in self.inner {
74            item.encode_to_bytes_buf_with_separator(string, separator);
75        }
76    }
77}
78
79impl<I> StringExtT for IterWrapper<I>
80where
81    I: Iterator,
82    I::Item: StringT,
83{
84    #[inline]
85    fn with_prefix<P: StringExtT + Copy>(self, prefix: P) -> impl StringExtT {
86        self.inner.map(move |item| super::tuple::SeplessTuple {
87            inner: (prefix, item),
88        })
89    }
90
91    #[inline]
92    fn with_suffix<S: StringExtT + Copy>(self, suffix: S) -> impl StringExtT {
93        self.inner.map(move |item| super::tuple::SeplessTuple {
94            inner: (item, suffix),
95        })
96    }
97}
98
99impl<T, I, F> StringT for std::iter::Map<I, F>
100where
101    T: StringT,
102    I: Iterator,
103    F: FnMut(I::Item) -> T,
104{
105    #[inline]
106    fn encode_to_buf(self, string: &mut Vec<u8>) {
107        str_iter_wrapper!(self.into_iter()).encode_to_buf(string);
108    }
109
110    #[inline]
111    fn encode_to_buf_with_separator(self, string: &mut Vec<u8>, separator: &str) {
112        str_iter_wrapper!(self.into_iter()).encode_to_buf_with_separator(string, separator);
113    }
114
115    #[inline]
116    fn encode_to_bytes_buf(self, string: &mut bytes::BytesMut) {
117        str_iter_wrapper!(self.into_iter()).encode_to_bytes_buf(string);
118    }
119
120    #[inline]
121    fn encode_to_bytes_buf_with_separator(self, string: &mut bytes::BytesMut, separator: &str) {
122        str_iter_wrapper!(self.into_iter()).encode_to_bytes_buf_with_separator(string, separator);
123    }
124}
125
126impl<T, I, F> StringExtT for std::iter::Map<I, F>
127where
128    T: StringT,
129    I: Iterator,
130    F: FnMut(I::Item) -> T,
131{
132    #[inline]
133    fn with_prefix<P: StringExtT + Copy>(self, prefix: P) -> impl StringExtT {
134        self.into_iter()
135            .map(move |item| super::tuple::SeplessTuple {
136                inner: (prefix, item),
137            })
138    }
139
140    #[inline]
141    fn with_suffix<S: StringExtT + Copy>(self, suffix: S) -> impl StringExtT {
142        self.into_iter()
143            .map(move |item| super::tuple::SeplessTuple {
144                inner: (item, suffix),
145            })
146    }
147}
148
149// ==============================================================================================
150
151macro_rules! impl_for_array_or_slice_like {
152    (STRING_T: $($tt:tt)*) => {
153        $($tt)* {
154            #[inline]
155            fn encode_to_buf(self, string: &mut Vec<u8>) {
156                str_iter_wrapper!(self.into_iter()).encode_to_buf(string);
157            }
158
159            #[inline]
160            fn encode_to_buf_with_separator(self, string: &mut Vec<u8>, separator: &str) {
161                str_iter_wrapper!(self.into_iter()).encode_to_buf_with_separator(string, separator);
162            }
163
164            #[inline]
165            fn encode_to_bytes_buf(self, string: &mut bytes::BytesMut) {
166                str_iter_wrapper!(self.into_iter()).encode_to_bytes_buf(string);
167            }
168
169            #[inline]
170            fn encode_to_bytes_buf_with_separator(self, string: &mut bytes::BytesMut, separator: &str) {
171                str_iter_wrapper!(self.into_iter()).encode_to_bytes_buf_with_separator(string, separator);
172            }
173        }
174    };
175    (STRING_EXT_T: $($tt:tt)*) => {
176        $($tt)* {
177            #[inline]
178            fn with_prefix<P: StringExtT + Copy>(self, prefix: P) -> impl StringExtT {
179                self.into_iter()
180                    .map(move |item| super::tuple::SeplessTuple {
181                        inner: (prefix, item),
182                    })
183            }
184
185            #[inline]
186            fn with_suffix<S: StringExtT + Copy>(self, suffix: S) -> impl StringExtT {
187                self.into_iter()
188                    .map(move |item| super::tuple::SeplessTuple {
189                        inner: (item, suffix),
190                    })
191            }
192        }
193    };
194}
195
196impl_for_array_or_slice_like!(STRING_T: impl<T, const N: usize> StringT for [T; N] where T: StringT);
197impl_for_array_or_slice_like!(STRING_EXT_T: impl<T, const N: usize> StringExtT for [T; N] where T: StringT);
198
199impl_for_array_or_slice_like!(STRING_T: impl<T, const N: usize> StringT for &[T; N] where for<'a> &'a T: StringT);
200impl_for_array_or_slice_like!(STRING_EXT_T: impl<T, const N: usize> StringExtT for &[T; N] where for<'a> &'a T: StringT);
201
202impl_for_array_or_slice_like!(STRING_T: impl<T> StringT for &[T] where for<'a> &'a T: StringT);
203impl_for_array_or_slice_like!(STRING_EXT_T: impl<T> StringExtT for &[T] where for<'a> &'a T: StringT);
204
205impl_for_array_or_slice_like!(STRING_T: impl<T> StringT for Vec<T> where T: StringT);
206impl_for_array_or_slice_like!(STRING_EXT_T: impl<T> StringExtT for Vec<T> where T: StringT);