bulks/adapters/
once.rs

1use core::{borrow::Borrow, marker::Destruct};
2
3use array_trait::length::LengthValue;
4
5use crate::{Bulk, DoubleEndedBulk, OnceWith, RandomAccessBulk, RepeatN, RepeatNWith, SplitBulk, StaticBulk, util::{FlatRef, TakeOne, YieldOnce}};
6
7/// Creates a bulk that yields an element exactly once.
8/// 
9/// Similar to [`core::iter::once`].
10///
11/// # Examples
12///
13/// Basic usage:
14///
15/// ```
16/// use bulks::*;
17///
18/// // one is the loneliest number
19/// let mut one: [_; _] = bulks::once(1).collect();
20///
21/// // just one, that's all we get
22/// assert_eq!(one, [1])
23/// ```
24pub const fn once<T>(value: T) -> Once<T>
25{
26    Once(value)
27}
28
29/// A bulk that yields an element exactly once.
30///
31/// This `struct` is created by the [`once()`] function. See its documentation for more.
32#[must_use = "bulks are lazy and do nothing unless consumed"]
33#[derive(Clone, Debug)]
34pub struct Once<T>(T);
35
36impl<T> IntoIterator for Once<T>
37{
38    type Item = T;
39    type IntoIter = core::iter::Once<T>;
40
41    fn into_iter(self) -> Self::IntoIter
42    {
43        core::iter::once(self.0)
44    }
45}
46impl<T> const Bulk for Once<T>
47{
48    type MinLength = [(); 1];
49    type MaxLength = [(); 1];
50
51    fn len(&self) -> usize
52    {
53        1
54    }
55    fn is_empty(&self) -> bool
56    {
57        false
58    }
59
60    fn first(self) -> Option<Self::Item>
61    where
62        Self::Item: ~const Destruct,
63        Self: Sized
64    {
65        Some(self.0)
66    }
67    fn last(self) -> Option<Self::Item>
68    where
69        Self::Item: ~const Destruct,
70        Self: Sized
71    {
72        Some(self.0)
73    }
74
75    fn for_each<FF>(self, mut f: FF)
76    where
77        Self: Sized,
78        FF: ~const FnMut(Self::Item) + ~const Destruct
79    {
80        f(self.0)
81    }
82    fn try_for_each<FF, R>(self, mut f: FF) -> R
83    where
84        Self: Sized,
85        Self::Item: ~const Destruct,
86        FF: ~const FnMut(Self::Item) -> R + ~const Destruct,
87        R: ~const core::ops::Try<Output = (), Residual: ~const Destruct>
88    {
89        f(self.0)
90    }
91}
92impl<T> const DoubleEndedBulk for Once<T>
93{
94    fn rev_for_each<FF>(self, f: FF)
95    where
96        Self: Sized,
97        FF: ~const FnMut(Self::Item) + ~const Destruct
98    {
99        self.for_each(f);
100    }
101    fn try_rev_for_each<FF, R>(self, f: FF) -> R
102    where
103        Self: Sized,
104        Self::Item: ~const Destruct,
105        FF: ~const FnMut(Self::Item) -> R + ~const Destruct,
106        R: ~const core::ops::Try<Output = (), Residual: ~const Destruct>
107    {
108        self.try_for_each(f)
109    }
110}
111impl<A, L> const SplitBulk<L> for Once<A>
112where
113    L: LengthValue,
114    OnceWith<YieldOnce<A>>: ~const SplitBulk<L, Item = A, Left: ~const Bulk, Right: ~const Bulk>
115{
116    type Left = <OnceWith<YieldOnce<A>> as SplitBulk<L>>::Left;
117    type Right = <OnceWith<YieldOnce<A>> as SplitBulk<L>>::Right;
118
119    fn split_at(bulk: Self, n: L) -> (Self::Left, Self::Right)
120    where
121        Self: Sized
122    {
123        OnceWith::from(bulk).split_at(n)
124    }
125}
126impl<'a, T, R> const RandomAccessBulk<'a> for Once<T>
127where
128    Self: 'a,
129    T: FlatRef<'a, FlatRef = R>,
130    &'a T: ~const Borrow<R>,
131    R: FlatRef<'a, FlatRef = R> + ~const Destruct + Copy + 'a,
132{
133    type ItemRef = R;
134    type EachRef = Once<R>;
135
136    fn each_ref(Self(value): &'a Self) -> Self::EachRef
137    {
138        crate::once(*(&value).borrow())
139    }
140}
141
142pub const trait OnceBulk: ~const DoubleEndedBulk + StaticBulk<Array<<Self as IntoIterator>::Item> = [<Self as IntoIterator>::Item; 1]>
143{
144
145}
146impl<T> const OnceBulk for T
147where
148    T: ~const DoubleEndedBulk + StaticBulk<Array<<Self as IntoIterator>::Item> = [<Self as IntoIterator>::Item; 1]>
149{
150
151}
152impl<A> const From<Once<A>> for OnceWith<YieldOnce<A>>
153{
154    fn from(value: Once<A>) -> Self
155    {
156        crate::once_with(YieldOnce::new(value.0))
157    }
158}
159impl<A> const From<Once<A>> for RepeatN<A, [(); 1]>
160where
161    A: Clone
162{
163    fn from(value: Once<A>) -> Self
164    {
165        crate::repeat_n(value.0, [(); 1])
166    }
167}
168impl<A> const From<Once<A>> for RepeatNWith<TakeOne<YieldOnce<A>>, [(); 1]>
169{
170    fn from(value: Once<A>) -> Self
171    {
172        crate::repeat_n_with(TakeOne::new(YieldOnce::new(value.0)), [(); 1])
173    }
174}
175
176#[cfg(test)]
177mod test
178{
179    use crate::Bulk;
180
181    #[test]
182    fn it_works()
183    {
184        let a = const {
185            crate::once(1).collect::<[_; _], _>()
186        };
187        assert_eq!(a, [1])
188    }
189}