alkahest/
iter.rs

1use crate::{
2    buffer::Buffer,
3    deserialize::DeserializeError,
4    formula::Formula,
5    serialize::{field_size_hint, write_slice, Serialize, Sizes},
6    size::{FixedUsize, SIZE_STACK},
7};
8
9const ITER_UPPER: usize = 4;
10
11/// Returns the size of the serialized data if it can be determined fast.
12#[inline(always)]
13pub fn default_iter_fast_sizes<F, I>(iter: &I) -> Option<Sizes>
14where
15    F: Formula + ?Sized,
16    I: Iterator,
17    I::Item: Serialize<F>,
18{
19    match (F::HEAPLESS, F::MAX_STACK_SIZE) {
20        (true, Some(0)) => Some(Sizes::with_stack(SIZE_STACK)),
21        (true, Some(max_stack)) => {
22            let (lower, upper) = iter.size_hint();
23            match upper {
24                Some(upper) if upper == lower => {
25                    // Expect this to be the truth.
26                    // If not, serialization will fail or produce incorrect results.
27                    Some(Sizes::with_stack(lower * max_stack))
28                }
29                _ => None,
30            }
31        }
32        _ => None,
33    }
34}
35
36/// Returns the size of the serialized data if it can be determined fast.
37#[inline(always)]
38pub fn ref_iter_fast_sizes<'a, F, I, T: 'a>(iter: I) -> Option<Sizes>
39where
40    F: Formula + ?Sized,
41    I: Iterator<Item = &'a T>,
42    T: Serialize<F>,
43{
44    match (F::HEAPLESS, F::MAX_STACK_SIZE) {
45        (true, Some(0)) => Some(Sizes::with_stack(SIZE_STACK)),
46        (true, Some(max_stack)) => {
47            let (lower, upper) = iter.size_hint();
48            match upper {
49                Some(upper) if upper == lower => {
50                    // Expect this to be the truth.
51                    // If not, serialization will fail or produce incorrect results.
52                    Some(Sizes::with_stack(lower * max_stack))
53                }
54                _ => None,
55            }
56        }
57        _ => {
58            let (_lower, upper) = iter.size_hint();
59            if upper.map_or(false, |upper| upper <= ITER_UPPER) {
60                let mut sizes = Sizes::ZERO;
61                for elem in iter {
62                    sizes += field_size_hint::<F>(elem, false)?;
63                }
64                return Some(sizes);
65            }
66            None
67        }
68    }
69}
70
71/// Returns the size of the serialized data if it can be determined fast.
72#[inline(always)]
73pub fn owned_iter_fast_sizes<F, I, T>(iter: I) -> Option<Sizes>
74where
75    F: Formula + ?Sized,
76    I: Iterator<Item = T>,
77    T: Serialize<F>,
78{
79    match (F::HEAPLESS, F::MAX_STACK_SIZE) {
80        (true, Some(0)) => Some(Sizes::with_stack(SIZE_STACK)),
81        (true, Some(max_stack)) => {
82            let (lower, upper) = iter.size_hint();
83            match upper {
84                Some(upper) if upper == lower => {
85                    // Expect this to be the truth.
86                    // If not, serialization will fail or produce incorrect results.
87                    Some(Sizes::with_stack(lower * max_stack))
88                }
89                _ => None,
90            }
91        }
92        _ => {
93            let (_lower, upper) = iter.size_hint();
94            if upper.map_or(false, |upper| upper <= ITER_UPPER) {
95                let mut sizes = Sizes::ZERO;
96                for elem in iter {
97                    sizes += field_size_hint::<F>(&elem, false)?;
98                }
99                return Some(sizes);
100            }
101            None
102        }
103    }
104}
105
106macro_rules! serialize_iter_to_slice {
107    ($F:ty : $self:expr => $sizes:ident, $buffer:ident) => {{
108        write_slice::<$F, _, _>($self, $sizes, $buffer)
109    }};
110}
111
112/// Iterator wrapper serializable with slice formula.
113/// Many standard library iterators implement serialization.
114/// For others this wrapper can be used without performance penalty.
115#[derive(Clone, Copy, Debug, PartialEq, Eq)]
116#[repr(transparent)]
117pub struct SerIter<T>(pub T);
118
119impl<F, T, I> Serialize<[F]> for SerIter<I>
120where
121    F: Formula,
122    I: Iterator<Item = T>,
123    T: Serialize<F>,
124{
125    #[inline(always)]
126    fn serialize<B>(self, sizes: &mut Sizes, buffer: B) -> Result<(), B::Error>
127    where
128        B: Buffer,
129    {
130        serialize_iter_to_slice!(F : self.0 => sizes, buffer)
131    }
132
133    #[inline(always)]
134    fn size_hint(&self) -> Option<Sizes> {
135        default_iter_fast_sizes::<F, I>(&self.0)
136    }
137}
138
139impl<F, T> Serialize<[F]> for core::ops::Range<T>
140where
141    F: Formula,
142    T: Serialize<F>,
143    core::ops::Range<T>: Iterator<Item = T>,
144{
145    #[inline(always)]
146    fn serialize<B>(self, sizes: &mut Sizes, buffer: B) -> Result<(), B::Error>
147    where
148        B: Buffer,
149    {
150        serialize_iter_to_slice!(F : self => sizes, buffer)
151    }
152
153    #[inline(always)]
154    fn size_hint(&self) -> Option<Sizes> {
155        default_iter_fast_sizes::<F, _>(self)
156    }
157}
158
159impl<F, T> Serialize<[F]> for core::ops::RangeInclusive<T>
160where
161    F: Formula,
162    T: Serialize<F>,
163    core::ops::RangeInclusive<T>: Iterator<Item = T>,
164{
165    #[inline(always)]
166    fn serialize<B>(self, sizes: &mut Sizes, buffer: B) -> Result<(), B::Error>
167    where
168        B: Buffer,
169    {
170        serialize_iter_to_slice!(F : self => sizes, buffer)
171    }
172
173    #[inline(always)]
174    fn size_hint(&self) -> Option<Sizes> {
175        default_iter_fast_sizes::<F, _>(self)
176    }
177}
178
179impl<F, X, Y, T> Serialize<[F]> for core::iter::Chain<X, Y>
180where
181    F: Formula,
182    X: Iterator<Item = T>,
183    Y: Iterator<Item = T>,
184    T: Serialize<F>,
185{
186    #[inline(always)]
187    fn serialize<B>(self, sizes: &mut Sizes, buffer: B) -> Result<(), B::Error>
188    where
189        B: Buffer,
190    {
191        serialize_iter_to_slice!(F : self => sizes, buffer)
192    }
193
194    #[inline(always)]
195    fn size_hint(&self) -> Option<Sizes> {
196        default_iter_fast_sizes::<F, _>(self)
197    }
198}
199
200impl<'a, F, I, T> Serialize<[F]> for core::iter::Cloned<I>
201where
202    F: Formula,
203    I: Iterator<Item = &'a T>,
204    T: Clone + Serialize<F> + 'a,
205{
206    #[inline(always)]
207    fn serialize<B>(self, sizes: &mut Sizes, buffer: B) -> Result<(), B::Error>
208    where
209        B: Buffer,
210    {
211        serialize_iter_to_slice!(F : self => sizes, buffer)
212    }
213
214    #[inline(always)]
215    fn size_hint(&self) -> Option<Sizes> {
216        default_iter_fast_sizes::<F, _>(self)
217    }
218}
219
220impl<'a, F, I, T> Serialize<[F]> for core::iter::Copied<I>
221where
222    F: Formula,
223    I: Iterator<Item = &'a T>,
224    T: Copy + Serialize<F> + 'a,
225{
226    #[inline(always)]
227    fn serialize<B>(self, sizes: &mut Sizes, buffer: B) -> Result<(), B::Error>
228    where
229        B: Buffer,
230    {
231        serialize_iter_to_slice!(F : self => sizes, buffer)
232    }
233
234    #[inline(always)]
235    fn size_hint(&self) -> Option<Sizes> {
236        default_iter_fast_sizes::<F, _>(self)
237    }
238}
239
240impl<F, T> Serialize<[F]> for core::iter::Empty<T>
241where
242    F: Formula,
243    T: Copy + Serialize<F>,
244{
245    #[inline(always)]
246    fn serialize<B>(self, sizes: &mut Sizes, buffer: B) -> Result<(), B::Error>
247    where
248        B: Buffer,
249    {
250        serialize_iter_to_slice!(F : self => sizes, buffer)
251    }
252
253    #[inline(always)]
254    fn size_hint(&self) -> Option<Sizes> {
255        Some(Sizes::ZERO)
256    }
257}
258
259// Typically `usize` is not serializable.
260// But lib makes exception for `usize`s that are derived from actual sizes.
261impl<F, I, T> Serialize<[(FixedUsize, F)]> for core::iter::Enumerate<I>
262where
263    F: Formula,
264    I: Iterator<Item = T>,
265    T: Serialize<F>,
266{
267    #[inline(always)]
268    fn serialize<B>(self, sizes: &mut Sizes, buffer: B) -> Result<(), B::Error>
269    where
270        B: Buffer,
271    {
272        serialize_iter_to_slice!((FixedUsize, F) : self => sizes, buffer)
273    }
274
275    #[inline(always)]
276    fn size_hint(&self) -> Option<Sizes> {
277        default_iter_fast_sizes::<(FixedUsize, F), _>(self)
278    }
279}
280
281impl<F, I, T, P> Serialize<[F]> for core::iter::Filter<I, P>
282where
283    F: Formula,
284    I: Iterator<Item = T>,
285    P: FnMut(&T) -> bool,
286    T: Serialize<F>,
287{
288    #[inline(always)]
289    fn serialize<B>(self, sizes: &mut Sizes, buffer: B) -> Result<(), B::Error>
290    where
291        B: Buffer,
292    {
293        serialize_iter_to_slice!(F : self => sizes, buffer)
294    }
295
296    #[inline(always)]
297    fn size_hint(&self) -> Option<Sizes> {
298        default_iter_fast_sizes::<F, _>(self)
299    }
300}
301
302impl<F, I, T, P> Serialize<[F]> for core::iter::FilterMap<I, P>
303where
304    F: Formula,
305    I: Iterator,
306    P: FnMut(I::Item) -> Option<T>,
307    T: Serialize<F>,
308{
309    #[inline(always)]
310    fn serialize<B>(self, sizes: &mut Sizes, buffer: B) -> Result<(), B::Error>
311    where
312        B: Buffer,
313    {
314        serialize_iter_to_slice!(F : self => sizes, buffer)
315    }
316
317    #[inline(always)]
318    fn size_hint(&self) -> Option<Sizes> {
319        default_iter_fast_sizes::<F, _>(self)
320    }
321}
322
323impl<F, I, X, U, T> Serialize<[F]> for core::iter::FlatMap<I, U, X>
324where
325    F: Formula,
326    I: Iterator,
327    X: FnMut(I::Item) -> U,
328    U: IntoIterator<Item = T>,
329    T: Serialize<F>,
330{
331    #[inline(always)]
332    fn serialize<B>(self, sizes: &mut Sizes, buffer: B) -> Result<(), B::Error>
333    where
334        B: Buffer,
335    {
336        serialize_iter_to_slice!(F : self => sizes, buffer)
337    }
338
339    #[inline(always)]
340    fn size_hint(&self) -> Option<Sizes> {
341        default_iter_fast_sizes::<F, _>(self)
342    }
343}
344
345impl<F, I, T> Serialize<[F]> for core::iter::Flatten<I>
346where
347    F: Formula,
348    I: Iterator,
349    I::Item: IntoIterator<Item = T>,
350    T: Serialize<F>,
351{
352    #[inline(always)]
353    fn serialize<B>(self, sizes: &mut Sizes, buffer: B) -> Result<(), B::Error>
354    where
355        B: Buffer,
356    {
357        serialize_iter_to_slice!(F : self => sizes, buffer)
358    }
359
360    #[inline(always)]
361    fn size_hint(&self) -> Option<Sizes> {
362        default_iter_fast_sizes::<F, _>(self)
363    }
364}
365
366impl<F, P, T> Serialize<[F]> for core::iter::FromFn<P>
367where
368    F: Formula,
369    P: FnMut() -> Option<T>,
370    T: Serialize<F>,
371{
372    #[inline(always)]
373    fn serialize<B>(self, sizes: &mut Sizes, buffer: B) -> Result<(), B::Error>
374    where
375        B: Buffer,
376    {
377        serialize_iter_to_slice!(F : self => sizes, buffer)
378    }
379
380    #[inline(always)]
381    fn size_hint(&self) -> Option<Sizes> {
382        default_iter_fast_sizes::<F, _>(self)
383    }
384}
385
386impl<F, I, T> Serialize<[F]> for core::iter::Fuse<I>
387where
388    F: Formula,
389    I: Iterator<Item = T>,
390    T: Serialize<F>,
391{
392    #[inline(always)]
393    fn serialize<B>(self, sizes: &mut Sizes, buffer: B) -> Result<(), B::Error>
394    where
395        B: Buffer,
396    {
397        serialize_iter_to_slice!(F : self => sizes, buffer)
398    }
399
400    #[inline(always)]
401    fn size_hint(&self) -> Option<Sizes> {
402        default_iter_fast_sizes::<F, _>(self)
403    }
404}
405
406impl<F, I, T, X> Serialize<[F]> for core::iter::Inspect<I, X>
407where
408    F: Formula,
409    I: Iterator<Item = T>,
410    T: Serialize<F>,
411    X: FnMut(&T),
412{
413    #[inline(always)]
414    fn serialize<B>(self, sizes: &mut Sizes, buffer: B) -> Result<(), B::Error>
415    where
416        B: Buffer,
417    {
418        serialize_iter_to_slice!(F : self => sizes, buffer)
419    }
420
421    #[inline(always)]
422    fn size_hint(&self) -> Option<Sizes> {
423        default_iter_fast_sizes::<F, _>(self)
424    }
425}
426
427impl<F, I, T, P> Serialize<[F]> for core::iter::Map<I, P>
428where
429    F: Formula,
430    I: Iterator,
431    P: FnMut(I::Item) -> T,
432    T: Serialize<F>,
433{
434    #[inline(always)]
435    fn serialize<B>(self, sizes: &mut Sizes, buffer: B) -> Result<(), B::Error>
436    where
437        B: Buffer,
438    {
439        serialize_iter_to_slice!(F : self => sizes, buffer)
440    }
441
442    #[inline(always)]
443    fn size_hint(&self) -> Option<Sizes> {
444        default_iter_fast_sizes::<F, _>(self)
445    }
446}
447
448impl<F, I, T, P> Serialize<[F]> for core::iter::MapWhile<I, P>
449where
450    F: Formula,
451    I: Iterator,
452    P: FnMut(I::Item) -> Option<T>,
453    T: Serialize<F>,
454{
455    #[inline(always)]
456    fn serialize<B>(self, sizes: &mut Sizes, buffer: B) -> Result<(), B::Error>
457    where
458        B: Buffer,
459    {
460        serialize_iter_to_slice!(F : self => sizes, buffer)
461    }
462
463    #[inline(always)]
464    fn size_hint(&self) -> Option<Sizes> {
465        default_iter_fast_sizes::<F, _>(self)
466    }
467}
468
469impl<F, T> Serialize<[F]> for core::iter::Once<T>
470where
471    F: Formula,
472    T: Serialize<F>,
473{
474    #[inline(always)]
475    fn serialize<B>(self, sizes: &mut Sizes, buffer: B) -> Result<(), B::Error>
476    where
477        B: Buffer,
478    {
479        serialize_iter_to_slice!(F : self => sizes, buffer)
480    }
481
482    #[inline(always)]
483    fn size_hint(&self) -> Option<Sizes> {
484        default_iter_fast_sizes::<F, _>(self)
485    }
486}
487
488impl<F, T, P> Serialize<[F]> for core::iter::OnceWith<P>
489where
490    F: Formula,
491    P: FnOnce() -> T,
492    T: Serialize<F>,
493{
494    #[inline(always)]
495    fn serialize<B>(self, sizes: &mut Sizes, buffer: B) -> Result<(), B::Error>
496    where
497        B: Buffer,
498    {
499        serialize_iter_to_slice!(F : self => sizes, buffer)
500    }
501
502    #[inline(always)]
503    fn size_hint(&self) -> Option<Sizes> {
504        default_iter_fast_sizes::<F, _>(self)
505    }
506}
507
508impl<F, I, T> Serialize<[F]> for core::iter::Peekable<I>
509where
510    F: Formula,
511    I: Iterator<Item = T>,
512    T: Serialize<F>,
513{
514    #[inline(always)]
515    fn serialize<B>(self, sizes: &mut Sizes, buffer: B) -> Result<(), B::Error>
516    where
517        B: Buffer,
518    {
519        serialize_iter_to_slice!(F : self => sizes, buffer)
520    }
521
522    #[inline(always)]
523    fn size_hint(&self) -> Option<Sizes> {
524        default_iter_fast_sizes::<F, _>(self)
525    }
526}
527
528impl<F, I, T> Serialize<[F]> for core::iter::Rev<I>
529where
530    F: Formula,
531    I: DoubleEndedIterator<Item = T>,
532    T: Serialize<F>,
533{
534    #[inline(always)]
535    fn serialize<B>(self, sizes: &mut Sizes, buffer: B) -> Result<(), B::Error>
536    where
537        B: Buffer,
538    {
539        serialize_iter_to_slice!(F : self => sizes, buffer)
540    }
541
542    #[inline(always)]
543    fn size_hint(&self) -> Option<Sizes> {
544        default_iter_fast_sizes::<F, _>(self)
545    }
546}
547
548impl<F, I, St, P, T> Serialize<[F]> for core::iter::Scan<I, St, P>
549where
550    F: Formula,
551    I: Iterator,
552    P: FnMut(&mut St, I::Item) -> Option<T>,
553    T: Serialize<F>,
554{
555    #[inline(always)]
556    fn serialize<B>(self, sizes: &mut Sizes, buffer: B) -> Result<(), B::Error>
557    where
558        B: Buffer,
559    {
560        serialize_iter_to_slice!(F : self => sizes, buffer)
561    }
562
563    #[inline(always)]
564    fn size_hint(&self) -> Option<Sizes> {
565        default_iter_fast_sizes::<F, _>(self)
566    }
567}
568
569impl<F, I, T> Serialize<[F]> for core::iter::Skip<I>
570where
571    F: Formula,
572    I: Iterator<Item = T>,
573    T: Serialize<F>,
574{
575    #[inline(always)]
576    fn serialize<B>(self, sizes: &mut Sizes, buffer: B) -> Result<(), B::Error>
577    where
578        B: Buffer,
579    {
580        serialize_iter_to_slice!(F : self => sizes, buffer)
581    }
582
583    #[inline(always)]
584    fn size_hint(&self) -> Option<Sizes> {
585        default_iter_fast_sizes::<F, _>(self)
586    }
587}
588
589impl<F, I, P, T> Serialize<[F]> for core::iter::SkipWhile<I, P>
590where
591    F: Formula,
592    I: Iterator<Item = T>,
593    P: FnMut(&T) -> bool,
594    T: Serialize<F>,
595{
596    #[inline(always)]
597    fn serialize<B>(self, sizes: &mut Sizes, buffer: B) -> Result<(), B::Error>
598    where
599        B: Buffer,
600    {
601        serialize_iter_to_slice!(F : self => sizes, buffer)
602    }
603
604    #[inline(always)]
605    fn size_hint(&self) -> Option<Sizes> {
606        default_iter_fast_sizes::<F, _>(self)
607    }
608}
609
610impl<F, I, T> Serialize<[F]> for core::iter::StepBy<I>
611where
612    F: Formula,
613    I: Iterator<Item = T>,
614    T: Serialize<F>,
615{
616    #[inline(always)]
617    fn serialize<B>(self, sizes: &mut Sizes, buffer: B) -> Result<(), B::Error>
618    where
619        B: Buffer,
620    {
621        serialize_iter_to_slice!(F : self => sizes, buffer)
622    }
623
624    #[inline(always)]
625    fn size_hint(&self) -> Option<Sizes> {
626        default_iter_fast_sizes::<F, _>(self)
627    }
628}
629
630impl<F, T, P> Serialize<[F]> for core::iter::Successors<T, P>
631where
632    F: Formula,
633    P: FnMut(&T) -> Option<T>,
634    T: Serialize<F>,
635{
636    #[inline(always)]
637    fn serialize<B>(self, sizes: &mut Sizes, buffer: B) -> Result<(), B::Error>
638    where
639        B: Buffer,
640    {
641        serialize_iter_to_slice!(F : self => sizes, buffer)
642    }
643
644    #[inline(always)]
645    fn size_hint(&self) -> Option<Sizes> {
646        default_iter_fast_sizes::<F, _>(self)
647    }
648}
649
650impl<F, I, T> Serialize<[F]> for core::iter::Take<I>
651where
652    F: Formula,
653    I: Iterator<Item = T>,
654    T: Serialize<F>,
655{
656    #[inline(always)]
657    fn serialize<B>(self, sizes: &mut Sizes, buffer: B) -> Result<(), B::Error>
658    where
659        B: Buffer,
660    {
661        serialize_iter_to_slice!(F : self => sizes, buffer)
662    }
663
664    #[inline(always)]
665    fn size_hint(&self) -> Option<Sizes> {
666        default_iter_fast_sizes::<F, _>(self)
667    }
668}
669
670impl<F, I, P, T> Serialize<[F]> for core::iter::TakeWhile<I, P>
671where
672    F: Formula,
673    I: Iterator<Item = T>,
674    P: FnMut(&T) -> bool,
675    T: Serialize<F>,
676{
677    #[inline(always)]
678    fn serialize<B>(self, sizes: &mut Sizes, buffer: B) -> Result<(), B::Error>
679    where
680        B: Buffer,
681    {
682        serialize_iter_to_slice!(F : self => sizes, buffer)
683    }
684
685    #[inline(always)]
686    fn size_hint(&self) -> Option<Sizes> {
687        default_iter_fast_sizes::<F, _>(self)
688    }
689}
690
691impl<FX, FY, X, Y> Serialize<[(FX, FY)]> for core::iter::Zip<X, Y>
692where
693    FX: Formula,
694    FY: Formula,
695    X: Iterator,
696    Y: Iterator,
697    X::Item: Serialize<FX>,
698    Y::Item: Serialize<FY>,
699{
700    #[inline(always)]
701    fn serialize<B>(self, sizes: &mut Sizes, buffer: B) -> Result<(), B::Error>
702    where
703        B: Buffer,
704    {
705        serialize_iter_to_slice!((FX, FY) : self => sizes, buffer)
706    }
707
708    #[inline(always)]
709    fn size_hint(&self) -> Option<Sizes> {
710        default_iter_fast_sizes::<(FX, FY), _>(self)
711    }
712}
713
714/// Deserialize `FromIterator` value from slice formula.
715///
716/// # Errors
717///
718/// Returns `DeserializeError` if deserialization fails.
719pub fn deserialize_from_iter<A, T>(
720    mut iter: impl Iterator<Item = Result<A, DeserializeError>>,
721) -> Result<T, DeserializeError>
722where
723    T: FromIterator<A>,
724{
725    let mut err = None;
726    let value = core::iter::from_fn(|| match iter.next() {
727        None => None,
728        Some(Ok(elem)) => Some(elem),
729        Some(Err(e)) => {
730            err = Some(e);
731            None
732        }
733    })
734    .collect();
735
736    match err {
737        None => Ok(value),
738        Some(e) => Err(e),
739    }
740}
741
742/// Deserialize into `Extend` value from slice formula.
743///
744/// # Errors
745///
746/// Returns `DeserializeError` if deserialization fails.
747#[inline(always)]
748pub fn deserialize_extend_iter<A, T>(
749    value: &mut T,
750    mut iter: impl Iterator<Item = Result<A, DeserializeError>>,
751) -> Result<(), DeserializeError>
752where
753    T: Extend<A>,
754{
755    let mut result = Ok(());
756    value.extend(core::iter::from_fn(|| match iter.next() {
757        None => None,
758        Some(Ok(elem)) => Some(elem),
759        Some(Err(err)) => {
760            result = Err(err);
761            None
762        }
763    }));
764    result
765}