1
0
mirror of https://github.com/fafhrd91/actix-net synced 2024-11-28 05:22:39 +01:00
actix-net/actix-connect/src/connect.rs

181 lines
3.9 KiB
Rust
Raw Normal View History

2019-03-13 20:40:11 +01:00
use std::collections::VecDeque;
use std::fmt;
use std::net::SocketAddr;
use either::Either;
2019-03-13 23:37:12 +01:00
/// Connect request
pub trait Address {
/// Host name of the request
fn host(&self) -> &str;
/// Port of the request
2019-03-14 06:51:31 +01:00
fn port(&self) -> Option<u16>;
2019-03-13 23:37:12 +01:00
}
2019-03-14 06:51:31 +01:00
impl Address for String {
2019-03-13 23:37:12 +01:00
fn host(&self) -> &str {
2019-03-14 06:51:31 +01:00
&self
2019-03-13 23:37:12 +01:00
}
2019-03-14 06:51:31 +01:00
fn port(&self) -> Option<u16> {
None
2019-03-13 23:37:12 +01:00
}
}
2019-03-14 06:51:31 +01:00
impl Address for &'static str {
2019-03-13 23:37:12 +01:00
fn host(&self) -> &str {
2019-03-14 06:51:31 +01:00
self
2019-03-13 23:37:12 +01:00
}
2019-03-14 06:51:31 +01:00
fn port(&self) -> Option<u16> {
None
2019-03-13 23:37:12 +01:00
}
}
2019-03-13 20:40:11 +01:00
/// Connect request
#[derive(Eq, PartialEq, Debug, Hash)]
2019-03-13 23:37:12 +01:00
pub struct Connect<T> {
pub(crate) req: T,
2019-03-14 06:51:31 +01:00
pub(crate) port: u16,
2019-03-13 23:37:12 +01:00
pub(crate) addr: Option<Either<SocketAddr, VecDeque<SocketAddr>>>,
}
2019-03-14 06:51:31 +01:00
impl<T: Address> Connect<T> {
/// Create `Connect` instance by spliting the string by ':' and convert the second part to u16
pub fn new(req: T) -> Connect<T> {
let (_, port) = parse(req.host());
2019-03-13 23:37:12 +01:00
Connect {
2019-03-14 06:51:31 +01:00
req,
port: port.unwrap_or(0),
2019-03-13 23:37:12 +01:00
addr: None,
2019-03-13 20:40:11 +01:00
}
}
/// Create new `Connect` instance from host and address. Connector skips name resolution stage for such connect messages.
2019-03-14 06:51:31 +01:00
pub fn with(req: T, addr: SocketAddr) -> Connect<T> {
2019-03-13 23:37:12 +01:00
Connect {
req,
2019-03-14 06:51:31 +01:00
port: 0,
2019-03-13 23:37:12 +01:00
addr: Some(Either::Left(addr)),
2019-03-13 20:40:11 +01:00
}
}
2019-03-14 19:15:32 +01:00
/// Use port if address does not provide one.
///
/// By default it set to 0
2019-03-14 06:55:01 +01:00
pub fn set_port(mut self, port: u16) -> Self {
self.port = port;
self
}
2019-04-20 02:43:52 +02:00
/// Use address.
pub fn set_addr(mut self, addr: Option<SocketAddr>) -> Self {
if let Some(addr) = addr {
self.addr = Some(Either::Left(addr));
}
self
}
2019-03-13 20:40:11 +01:00
/// Host name
2019-03-13 23:37:12 +01:00
pub fn host(&self) -> &str {
self.req.host()
}
/// Port of the request
pub fn port(&self) -> u16 {
2019-03-14 06:51:31 +01:00
self.req.port().unwrap_or(self.port)
}
}
impl<T: Address> From<T> for Connect<T> {
fn from(addr: T) -> Self {
Connect::new(addr)
2019-03-13 20:40:11 +01:00
}
}
2019-03-13 23:37:12 +01:00
impl<T: Address> fmt::Display for Connect<T> {
2019-03-13 20:40:11 +01:00
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2019-03-13 23:37:12 +01:00
write!(f, "{}:{}", self.host(), self.port())
2019-03-13 20:40:11 +01:00
}
}
2019-03-14 06:51:31 +01:00
fn parse(host: &str) -> (&str, Option<u16>) {
let mut parts_iter = host.splitn(2, ':');
if let Some(host) = parts_iter.next() {
let port_str = parts_iter.next().unwrap_or("");
if let Ok(port) = port_str.parse::<u16>() {
(host, Some(port))
} else {
(host, None)
}
} else {
(host, None)
}
}
2019-03-13 23:37:12 +01:00
pub struct Connection<T, U> {
io: U,
req: T,
2019-03-13 20:40:11 +01:00
}
2019-03-13 23:37:12 +01:00
impl<T, U> Connection<T, U> {
pub fn new(io: U, req: T) -> Self {
Self { io, req }
2019-03-13 20:40:11 +01:00
}
}
2019-03-13 23:37:12 +01:00
impl<T, U> Connection<T, U> {
2019-03-13 20:40:11 +01:00
/// Reconstruct from a parts.
2019-03-13 23:37:12 +01:00
pub fn from_parts(io: U, req: T) -> Self {
Self { io, req }
2019-03-13 20:40:11 +01:00
}
/// Deconstruct into a parts.
2019-03-13 23:37:12 +01:00
pub fn into_parts(self) -> (U, T) {
(self.io, self.req)
2019-03-13 20:40:11 +01:00
}
/// Replace inclosed object, return new Stream and old object
2019-03-13 23:37:12 +01:00
pub fn replace<Y>(self, io: Y) -> (U, Connection<T, Y>) {
(self.io, Connection { io, req: self.req })
2019-03-13 20:40:11 +01:00
}
/// Returns a shared reference to the underlying stream.
2019-03-13 23:37:12 +01:00
pub fn get_ref(&self) -> &U {
2019-03-13 20:40:11 +01:00
&self.io
}
/// Returns a mutable reference to the underlying stream.
2019-03-13 23:37:12 +01:00
pub fn get_mut(&mut self) -> &mut U {
2019-03-13 20:40:11 +01:00
&mut self.io
}
2019-03-13 23:37:12 +01:00
}
2019-03-13 20:40:11 +01:00
2019-03-13 23:37:12 +01:00
impl<T: Address, U> Connection<T, U> {
/// Get request
2019-03-13 20:40:11 +01:00
pub fn host(&self) -> &str {
2019-03-13 23:37:12 +01:00
&self.req.host()
2019-03-13 20:40:11 +01:00
}
}
2019-03-13 23:37:12 +01:00
impl<T, U> std::ops::Deref for Connection<T, U> {
type Target = U;
2019-03-13 20:40:11 +01:00
2019-03-13 23:37:12 +01:00
fn deref(&self) -> &U {
2019-03-13 20:40:11 +01:00
&self.io
}
}
2019-03-13 23:37:12 +01:00
impl<T, U> std::ops::DerefMut for Connection<T, U> {
fn deref_mut(&mut self) -> &mut U {
2019-03-13 20:40:11 +01:00
&mut self.io
}
}
2019-03-13 23:37:12 +01:00
impl<T, U: fmt::Debug> fmt::Debug for Connection<T, U> {
2019-03-13 20:40:11 +01:00
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Stream {{{:?}}}", self.io)
}
}