Skip to main content

const_size_flatten/
lib.rs

1#![no_std]
2//! Versions of [`FlatMap`] and [`Flatten`] that know their inner iterators’ size in advance.
3//! Note that `core` & `std` already provide this functionality for some types through a hack using specialization.
4//! This crate’s contribution is that the trait [`ConstSizeIntoIterator`] is public and the functionality is therefore extensible.
5//!
6//! To use, just `use const_size_flatten::IteratorExtension`.
7//!
8//! [`FlatMap`]: core::iter::FlatMap
9//! [`Flatten`]: core::iter::Flatten
10
11mod flatmap;
12pub use flatmap::*;
13mod flatten;
14pub use flatten::*;
15mod flatten_base;
16
17/// Implementors of this trait promise that all iterators they produce always produce the same number of elements.
18/// This number is given by the associated constant [`SIZE`].
19/// Note that this trait should not be implemented for [`Iterator`]s, since they can be iterated through,
20/// which changes the amount of elements they produce.
21///
22/// [`SIZE`]: ConstSizeIntoIterator::SIZE
23pub trait ConstSizeIntoIterator: IntoIterator {
24    const SIZE: usize;
25}
26
27impl<T, const N: usize> ConstSizeIntoIterator for [T; N] {
28    const SIZE: usize = N;
29}
30
31impl<T, const N: usize> ConstSizeIntoIterator for &[T; N] {
32    const SIZE: usize = N;
33}
34
35impl<T, const N: usize> ConstSizeIntoIterator for &mut [T; N] {
36    const SIZE: usize = N;
37}
38
39mod iterator_extension {
40    pub trait Sealed: IntoIterator {}
41    impl<T: IntoIterator> Sealed for T {}
42}
43
44/// Convenience `trait` that allows you to construct [`ConstSizeFlatten`] and [`ConstSizeFlatMap`].
45/// This trait is sealed, you cannot implement it.
46pub trait IteratorExtension: IntoIterator + iterator_extension::Sealed {
47    /// Construct a [`ConstSizeFlatten`] from an [`IntoIterator`] (which includes [`Iterator`]s).
48    /// This is the `impl` version of [`const_size_flatten`].
49    fn const_size_flatten(self) -> ConstSizeFlatten<Self::IntoIter>
50    where
51        Self: Sized,
52        Self::Item: IntoIterator,
53    {
54        const_size_flatten(self)
55    }
56
57    /// Construct a [`ConstSizeFlatMap`] from an [`IntoIterator`] (which includes [`Iterator`]s).
58    /// This is the `impl` version of [`const_size_flat_map`].
59    fn const_size_flat_map<U, F>(self, f: F) -> ConstSizeFlatMap<Self::IntoIter, U, F>
60    where
61        Self: Sized,
62        U: IntoIterator,
63        F: FnMut(Self::Item) -> U,
64    {
65        const_size_flat_map(self, f)
66    }
67}
68
69impl<T: IntoIterator> IteratorExtension for T {}