use std::borrow::Cow;
use std::fmt::{self, Debug, Formatter};
use std::iter::IntoIterator;
use std::net::SocketAddr;
use std::sync::{Arc, Mutex};
use tokio_core::reactor::Handle;
use {Resolve, Service};
use super::{FixedResolver, Resolver, Supervisor};
pub mod app;
pub mod locator;
pub mod storage;
pub mod tvm;
pub mod unicorn;
pub use self::app::App;
pub use self::locator::Locator;
pub use self::storage::Storage;
pub use self::tvm::Tvm;
pub use self::unicorn::Unicorn;
const LOCATOR_NAME: &str = "locator";
pub trait ResolveBuilder {
type Item: Resolve;
fn build(self, handle: &Handle) -> Self::Item;
}
#[derive(Debug)]
pub struct ResolverBuilder {
name: Cow<'static, str>,
resolver: FixedResolver,
}
impl ResolveBuilder for ResolverBuilder {
type Item = Resolver;
fn build(self, handle: &Handle) -> Self::Item {
let shared = Arc::new(Mutex::new(Default::default()));
let locator = Service {
name: self.name.clone(),
shared: shared.clone(),
tx: Supervisor::spawn(self.name, shared, self.resolver, handle),
};
Resolver::new(Locator::new(locator))
}
}
#[derive(Debug)]
pub struct PreparedResolver<R> {
resolver: R,
}
impl<R: Resolve> ResolveBuilder for PreparedResolver<R> {
type Item = R;
fn build(self, _handle: &Handle) -> Self::Item {
self.resolver
}
}
pub struct ServiceBuilder<T> {
name: Cow<'static, str>,
resolve_builder: T,
}
impl ServiceBuilder<ResolverBuilder> {
pub fn new<N: Into<Cow<'static, str>>>(name: N) -> Self {
let resolver = ResolverBuilder {
name: LOCATOR_NAME.into(),
resolver: FixedResolver::default(),
};
Self {
name: name.into(),
resolve_builder: resolver,
}
}
pub fn locator_addrs<E>(mut self, addrs: E) -> Self
where
E: IntoIterator<Item = SocketAddr>,
{
self.resolve_builder.resolver = FixedResolver::new(addrs.into_iter().collect());
self
}
pub fn memory_limit(self, _nbytes: usize) -> Self {
unimplemented!();
}
}
impl<T> ServiceBuilder<T> {
pub fn resolver<R: Resolve>(self, resolver: R) -> ServiceBuilder<PreparedResolver<R>> {
ServiceBuilder {
name: self.name,
resolve_builder: PreparedResolver { resolver: resolver },
}
}
}
impl<T: ResolveBuilder + 'static> ServiceBuilder<T> {
pub fn build(self, handle: &Handle) -> Service {
let shared = Arc::new(Mutex::new(Default::default()));
Service {
name: self.name.clone(),
shared: shared.clone(),
tx: Supervisor::spawn(self.name, shared, self.resolve_builder.build(handle), handle),
}
}
}
impl<T> Debug for ServiceBuilder<T> {
fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> {
fmt.debug_struct("ServiceBuilder")
.field("name", &self.name)
.finish()
}
}