• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use super::{error::Never, Change};
2 use futures_core::Stream;
3 use pin_project_lite::pin_project;
4 use std::iter::{Enumerate, IntoIterator};
5 use std::{
6     pin::Pin,
7     task::{Context, Poll},
8 };
9 use tower_service::Service;
10 
11 pin_project! {
12     /// Static service discovery based on a predetermined list of services.
13     ///
14     /// [`ServiceList`] is created with an initial list of services. The discovery
15     /// process will yield this list once and do nothing after.
16     #[derive(Debug)]
17     pub struct ServiceList<T>
18     where
19         T: IntoIterator,
20     {
21         inner: Enumerate<T::IntoIter>,
22     }
23 }
24 
25 impl<T, U> ServiceList<T>
26 where
27     T: IntoIterator<Item = U>,
28 {
29     #[allow(missing_docs)]
new<Request>(services: T) -> ServiceList<T> where U: Service<Request>,30     pub fn new<Request>(services: T) -> ServiceList<T>
31     where
32         U: Service<Request>,
33     {
34         ServiceList {
35             inner: services.into_iter().enumerate(),
36         }
37     }
38 }
39 
40 impl<T, U> Stream for ServiceList<T>
41 where
42     T: IntoIterator<Item = U>,
43 {
44     type Item = Result<Change<usize, U>, Never>;
45 
poll_next(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Option<Self::Item>>46     fn poll_next(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Option<Self::Item>> {
47         match self.project().inner.next() {
48             Some((i, service)) => Poll::Ready(Some(Ok(Change::Insert(i, service)))),
49             None => Poll::Ready(None),
50         }
51     }
52 }
53 
54 // check that List can be directly over collections
55 #[cfg(test)]
56 #[allow(dead_code)]
57 type ListVecTest<T> = ServiceList<Vec<T>>;
58 
59 #[cfg(test)]
60 #[allow(dead_code)]
61 type ListVecIterTest<T> = ServiceList<::std::vec::IntoIter<T>>;
62