discover: polish crate (#194)
This commit is contained in:
parent
acda5a75b9
commit
f8d88427aa
|
@ -0,0 +1,13 @@
|
|||
use std::error::Error;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Never {}
|
||||
|
||||
impl fmt::Display for Never {
|
||||
fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {}
|
||||
}
|
||||
}
|
||||
|
||||
impl Error for Never {}
|
|
@ -9,13 +9,15 @@
|
|||
extern crate futures;
|
||||
extern crate tower_service;
|
||||
|
||||
use futures::{Async, Poll, Stream};
|
||||
use tower_service::Service;
|
||||
mod error;
|
||||
mod list;
|
||||
mod stream;
|
||||
|
||||
use std::fmt;
|
||||
pub use crate::list::ServiceList;
|
||||
pub use crate::stream::ServiceStream;
|
||||
|
||||
use futures::Poll;
|
||||
use std::hash::Hash;
|
||||
use std::iter::{Enumerate, IntoIterator};
|
||||
use std::marker::PhantomData;
|
||||
|
||||
/// Provide a uniform set of services able to satisfy a request.
|
||||
///
|
||||
|
@ -41,111 +43,3 @@ pub enum Change<K, V> {
|
|||
Insert(K, V),
|
||||
Remove(K),
|
||||
}
|
||||
|
||||
/// Static service discovery based on a predetermined list of services.
|
||||
///
|
||||
/// `List` is created with an initial list of services. The discovery process
|
||||
/// will yield this list once and do nothing after.
|
||||
pub struct List<T>
|
||||
where
|
||||
T: IntoIterator,
|
||||
{
|
||||
inner: Enumerate<T::IntoIter>,
|
||||
}
|
||||
// ===== impl List =====
|
||||
|
||||
impl<T, U> List<T>
|
||||
where
|
||||
T: IntoIterator<Item = U>,
|
||||
{
|
||||
pub fn new<Request>(services: T) -> List<T>
|
||||
where
|
||||
U: Service<Request>,
|
||||
{
|
||||
List {
|
||||
inner: services.into_iter().enumerate(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, U> Discover for List<T>
|
||||
where
|
||||
T: IntoIterator<Item = U>,
|
||||
{
|
||||
type Key = usize;
|
||||
type Service = U;
|
||||
type Error = Never;
|
||||
|
||||
fn poll(&mut self) -> Poll<Change<Self::Key, Self::Service>, Self::Error> {
|
||||
match self.inner.next() {
|
||||
Some((i, service)) => Ok(Change::Insert(i, service).into()),
|
||||
None => Ok(Async::NotReady),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Dynamic service discovery based on a stream of service changes.
|
||||
pub struct Services<S, K, Svc> {
|
||||
inner: futures::stream::Fuse<S>,
|
||||
_marker_k: PhantomData<K>,
|
||||
_marker_v: PhantomData<Svc>,
|
||||
}
|
||||
|
||||
// ===== impl Services =====
|
||||
|
||||
impl<S, K, Svc> Services<S, K, Svc>
|
||||
where
|
||||
S: Stream<Item = Change<K, Svc>>,
|
||||
{
|
||||
pub fn new<Request>(services: S) -> Self
|
||||
where
|
||||
Svc: Service<Request>,
|
||||
{
|
||||
Services {
|
||||
inner: services.fuse(),
|
||||
_marker_k: PhantomData,
|
||||
_marker_v: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<S, K, Svc> Discover for Services<S, K, Svc>
|
||||
where
|
||||
K: Hash + Eq,
|
||||
S: Stream<Item = Change<K, Svc>>,
|
||||
{
|
||||
type Key = K;
|
||||
type Service = Svc;
|
||||
type Error = S::Error;
|
||||
|
||||
fn poll(&mut self) -> Poll<Change<Self::Key, Self::Service>, Self::Error> {
|
||||
match try_ready!(self.inner.poll()) {
|
||||
Some(c) => Ok(Async::Ready(c)),
|
||||
None => {
|
||||
// there are no more service changes coming
|
||||
Ok(Async::NotReady)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[derive(Debug)]
|
||||
pub enum Never {}
|
||||
|
||||
impl fmt::Display for Never {
|
||||
fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for Never {}
|
||||
|
||||
// check that List can be directly over collections
|
||||
#[cfg(test)]
|
||||
#[allow(dead_code)]
|
||||
type ListVecTest<T> = List<Vec<T>>;
|
||||
|
||||
#[cfg(test)]
|
||||
#[allow(dead_code)]
|
||||
type ListVecIterTest<T> = List<::std::vec::IntoIter<T>>;
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
use crate::error::Never;
|
||||
use crate::{Change, Discover};
|
||||
use futures::{Async, Poll};
|
||||
use std::iter::{Enumerate, IntoIterator};
|
||||
use tower_service::Service;
|
||||
|
||||
/// Static service discovery based on a predetermined list of services.
|
||||
///
|
||||
/// `ServiceList` is created with an initial list of services. The discovery
|
||||
/// process will yield this list once and do nothing after.
|
||||
pub struct ServiceList<T>
|
||||
where
|
||||
T: IntoIterator,
|
||||
{
|
||||
inner: Enumerate<T::IntoIter>,
|
||||
}
|
||||
|
||||
impl<T, U> ServiceList<T>
|
||||
where
|
||||
T: IntoIterator<Item = U>,
|
||||
{
|
||||
pub fn new<Request>(services: T) -> ServiceList<T>
|
||||
where
|
||||
U: Service<Request>,
|
||||
{
|
||||
ServiceList {
|
||||
inner: services.into_iter().enumerate(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, U> Discover for ServiceList<T>
|
||||
where
|
||||
T: IntoIterator<Item = U>,
|
||||
{
|
||||
type Key = usize;
|
||||
type Service = U;
|
||||
type Error = Never;
|
||||
|
||||
fn poll(&mut self) -> Poll<Change<Self::Key, Self::Service>, Self::Error> {
|
||||
match self.inner.next() {
|
||||
Some((i, service)) => Ok(Change::Insert(i, service).into()),
|
||||
None => Ok(Async::NotReady),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check that List can be directly over collections
|
||||
#[cfg(test)]
|
||||
#[allow(dead_code)]
|
||||
type ListVecTest<T> = ServiceList<Vec<T>>;
|
||||
|
||||
#[cfg(test)]
|
||||
#[allow(dead_code)]
|
||||
type ListVecIterTest<T> = ServiceList<::std::vec::IntoIter<T>>;
|
|
@ -0,0 +1,42 @@
|
|||
use crate::{Change, Discover};
|
||||
use futures::{Async, Poll, Stream};
|
||||
use std::hash::Hash;
|
||||
use tower_service::Service;
|
||||
|
||||
/// Dynamic service discovery based on a stream of service changes.
|
||||
pub struct ServiceStream<S> {
|
||||
inner: futures::stream::Fuse<S>,
|
||||
}
|
||||
|
||||
impl<S> ServiceStream<S> {
|
||||
pub fn new<K, Svc, Request>(services: S) -> Self
|
||||
where
|
||||
S: Stream<Item = Change<K, Svc>>,
|
||||
K: Hash + Eq,
|
||||
Svc: Service<Request>,
|
||||
{
|
||||
ServiceStream {
|
||||
inner: services.fuse(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<S, K, Svc> Discover for ServiceStream<S>
|
||||
where
|
||||
K: Hash + Eq,
|
||||
S: Stream<Item = Change<K, Svc>>,
|
||||
{
|
||||
type Key = K;
|
||||
type Service = Svc;
|
||||
type Error = S::Error;
|
||||
|
||||
fn poll(&mut self) -> Poll<Change<Self::Key, Self::Service>, Self::Error> {
|
||||
match try_ready!(self.inner.poll()) {
|
||||
Some(c) => Ok(Async::Ready(c)),
|
||||
None => {
|
||||
// there are no more service changes coming
|
||||
Ok(Async::NotReady)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue