extend_fn/
lib.rs

1#![cfg_attr(not(test), no_std)]
2//! [fn-mut]: `FnMut`
3//! [extend]: `core::iter::Extend`
4#![doc = include_str!("../README.md")]
5
6/// Use an arbitrary [`FnMut`] type to implement [`Extend`][extend].
7///
8/// ```rust
9/// use extend_fn::ExtendUsing; 
10///
11/// let numbers = [5, 2, 11usize];
12///
13/// let mut result = 1usize; 
14/// let mut extender = ExtendUsing::new(|value| result *= value);
15/// extender.extend(numbers.iter().copied());
16///
17/// assert_eq!(numbers.iter().product::<usize>(), result);
18/// ```
19///
20/// For cases where you are writing into an actual container and want to
21/// transform items before their addition, consider using the 
22/// [`extend_map` crate][extend-map] instead.
23///
24/// [extend]: `core::iter::Extend`
25/// [extend-map]: https://crates.io/crates/extend_map
26#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Default)]
27pub struct ExtendUsing<F: ?Sized>(pub F);
28
29impl<F> ExtendUsing<F> {
30    #[inline]
31    pub const fn new(f: F) -> Self {
32        Self(f)
33    }
34}
35
36impl<F> From<F> for ExtendUsing<F> {
37    #[inline]
38    fn from(value: F) -> Self {
39        Self::new(value) 
40    }
41}
42
43impl<Item, F: ?Sized + FnMut(Item)> Extend<Item> for ExtendUsing<F> {
44    #[inline]
45    fn extend<I: IntoIterator<Item = Item>>(&mut self, iter: I) {
46        for item in iter {
47            self.0(item)
48        }
49    }
50}
51
52// This Source Code Form is subject to the terms of the Mozilla Public
53// License, v. 2.0. If a copy of the MPL was not distributed with this
54// file, You can obtain one at http://mozilla.org/MPL/2.0/.