use std::net::{SocketAddr, SocketAddrV4, SocketAddrV6, Ipv4Addr};
use std::str::FromStr;
use std::any::TypeId;
use std::mem::swap;
use std::time::Duration;
use anymap::Map;
use anymap::any::{Any, UncheckedAnyExt};
pub enum Scheme {
Http,
#[cfg(feature = "ssl")]
Https {
cert: ::std::path::PathBuf,
key: ::std::path::PathBuf
}
}
#[derive(Eq, PartialEq, Debug, Hash, Clone, Copy)]
pub struct Host(SocketAddr);
impl Host {
pub fn any_v4(port: u16) -> Host {
Host(SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(0, 0, 0, 0), port)))
}
pub fn port(&mut self, port: u16) {
self.0 = match self.0 {
SocketAddr::V4(addr) => SocketAddr::V4(SocketAddrV4::new(addr.ip().clone(), port)),
SocketAddr::V6(addr) => {
SocketAddr::V6(SocketAddrV6::new(addr.ip().clone(), port, addr.flowinfo(), addr.scope_id()))
}
};
}
}
impl From<Host> for SocketAddr {
fn from(host: Host) -> SocketAddr {
host.0
}
}
impl From<u16> for Host {
fn from(port: u16) -> Host {
Host::any_v4(port)
}
}
impl From<SocketAddr> for Host {
fn from(addr: SocketAddr) -> Host {
Host(addr)
}
}
impl From<SocketAddrV4> for Host {
fn from(addr: SocketAddrV4) -> Host {
Host(SocketAddr::V4(addr))
}
}
impl From<SocketAddrV6> for Host {
fn from(addr: SocketAddrV6) -> Host {
Host(SocketAddr::V6(addr))
}
}
impl From<(Ipv4Addr, u16)> for Host {
fn from((ip, port): (Ipv4Addr, u16)) -> Host {
Host(SocketAddr::V4(SocketAddrV4::new(ip, port)))
}
}
impl FromStr for Host {
type Err = <SocketAddr as FromStr>::Err;
fn from_str(s: &str) -> Result<Host, Self::Err> {
s.parse().map(|s| Host(s))
}
}
pub struct Global(GlobalState);
impl Global {
pub fn get<T: Any + Send + Sync>(&self) -> Option<&T> {
match self.0 {
GlobalState::None => None,
GlobalState::One(id, ref a) => if id == TypeId::of::<T>() {
unsafe { Some(a.downcast_ref_unchecked()) }
} else {
None
},
GlobalState::Many(ref map) => map.get()
}
}
pub fn insert<T: Any + Send + Sync>(&mut self, value: T) -> Option<T> {
match self.0 {
GlobalState::None => {
*self = Box::new(value).into();
None
},
GlobalState::One(id, _) => if id == TypeId::of::<T>() {
if let GlobalState::One(_, ref mut previous_value) = self.0 {
let mut v = Box::new(value) as Box<Any + Send + Sync>;
swap(previous_value, &mut v);
Some(unsafe { *v.downcast_unchecked() })
} else {
unreachable!()
}
} else {
let mut other = GlobalState::Many(Map::new());
swap(&mut self.0, &mut other);
if let GlobalState::Many(ref mut map) = self.0 {
if let GlobalState::One(id, previous_value) = other {
let mut raw = map.as_mut();
unsafe { raw.insert(id, previous_value); }
}
map.insert(value)
} else {
unreachable!()
}
},
GlobalState::Many(ref mut map) => {
map.insert(value)
}
}
}
}
impl<T: Any + Send + Sync> From<Box<T>> for Global {
fn from(data: Box<T>) -> Global {
Global(GlobalState::One(TypeId::of::<T>(), data))
}
}
macro_rules! from_tuple {
($first: ident, $($t: ident),+) => (
impl<$first: Any + Send + Sync, $($t: Any + Send + Sync),+> From<($first, $($t),+)> for Global {
#[allow(non_snake_case)]
fn from(tuple: ($first, $($t),+))-> Global {
let ($first, $($t),+) = tuple;
let mut map = Map::new();
map.insert($first);
$(
map.insert($t);
)+
Global(GlobalState::Many(map))
}
}
from_tuple!($($t),+);
);
($ty: ident) => (
impl<$ty: Any + Send + Sync> From<($ty,)> for Global {
fn from(tuple: ($ty,)) -> Global {
Box::new(tuple.0).into()
}
}
);
}
impl From<()> for Global {
fn from(_: ()) -> Global {
Global(GlobalState::None)
}
}
from_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);
impl Default for Global {
fn default() -> Global {
Global(GlobalState::None)
}
}
enum GlobalState {
None,
One(TypeId, Box<Any + Send + Sync>),
Many(Map<Any + Send + Sync>),
}
pub struct KeepAlive {
pub timeout: Duration,
pub free_threads: usize,
}