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/.