aws_smithy_async/future/pagination_stream/
collect.rs

1/*
2 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6//! Module to extend the functionality of types in `patination_stream` module to allow for
7//! collecting elements of the stream into collection.
8//!
9//! Majority of the code is borrowed from
10//! <https://github.com/tokio-rs/tokio/blob/fc9518b62714daac9a38b46c698b94ac5d5b1ca2/tokio-stream/src/stream_ext/collect.rs>
11
12pub(crate) mod sealed {
13    /// A trait that signifies that elements can be collected into `T`.
14    ///
15    /// Currently the trait may not be implemented by clients so we can make changes in the future
16    /// without breaking code depending on it.
17    pub trait Collectable<T> {
18        type Collection;
19
20        fn initialize() -> Self::Collection;
21
22        fn extend(collection: &mut Self::Collection, item: T) -> bool;
23
24        fn finalize(collection: Self::Collection) -> Self;
25    }
26}
27
28impl<T> sealed::Collectable<T> for Vec<T> {
29    type Collection = Self;
30
31    fn initialize() -> Self::Collection {
32        Vec::default()
33    }
34
35    fn extend(collection: &mut Self::Collection, item: T) -> bool {
36        collection.push(item);
37        true
38    }
39
40    fn finalize(collection: Self::Collection) -> Self {
41        collection
42    }
43}
44
45impl<T, U, E> sealed::Collectable<Result<T, E>> for Result<U, E>
46where
47    U: sealed::Collectable<T>,
48{
49    type Collection = Result<U::Collection, E>;
50
51    fn initialize() -> Self::Collection {
52        Ok(U::initialize())
53    }
54
55    fn extend(collection: &mut Self::Collection, item: Result<T, E>) -> bool {
56        match item {
57            Ok(item) => {
58                let collection = collection.as_mut().ok().expect("invalid state");
59                U::extend(collection, item)
60            }
61            Err(e) => {
62                *collection = Err(e);
63                false
64            }
65        }
66    }
67
68    fn finalize(collection: Self::Collection) -> Self {
69        match collection {
70            Ok(collection) => Ok(U::finalize(collection)),
71            err @ Err(_) => Err(err.map(drop).unwrap_err()),
72        }
73    }
74}