1use super::Change;
2use futures_core::Stream;
3use pin_project_lite::pin_project;
4use std::convert::Infallible;
5use std::iter::{Enumerate, IntoIterator};
6use std::{
7 pin::Pin,
8 task::{Context, Poll},
9};
10use tower_service::Service;
11
12pin_project! {
13 #[derive(Debug)]
18 pub struct ServiceList<T>
19 where
20 T: IntoIterator,
21 {
22 inner: Enumerate<T::IntoIter>,
23 }
24}
25
26impl<T, U> ServiceList<T>
27where
28 T: IntoIterator<Item = U>,
29{
30 #[allow(missing_docs)]
31 pub fn new<Request>(services: T) -> ServiceList<T>
32 where
33 U: Service<Request>,
34 {
35 ServiceList {
36 inner: services.into_iter().enumerate(),
37 }
38 }
39}
40
41impl<T, U> Stream for ServiceList<T>
42where
43 T: IntoIterator<Item = U>,
44{
45 type Item = Result<Change<usize, U>, Infallible>;
46
47 fn poll_next(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Option<Self::Item>> {
48 match self.project().inner.next() {
49 Some((i, service)) => Poll::Ready(Some(Ok(Change::Insert(i, service)))),
50 None => Poll::Ready(None),
51 }
52 }
53}
54
55#[cfg(test)]
57#[allow(dead_code)]
58type ListVecTest<T> = ServiceList<Vec<T>>;
59
60#[cfg(test)]
61#[allow(dead_code)]
62type ListVecIterTest<T> = ServiceList<::std::vec::IntoIter<T>>;