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