1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
use std::cell::Cell;
use std::fmt;
use std::net::SocketAddr;
use std::rc::Rc;

#[derive(Debug, Clone)]
pub struct ServerConfig {
    addr: SocketAddr,
    secure: Rc<Cell<bool>>,
}

impl ServerConfig {
    pub fn new(addr: SocketAddr) -> Self {
        ServerConfig {
            addr,
            secure: Rc::new(Cell::new(false)),
        }
    }

    /// Returns the address of the local half of this TCP server socket
    pub fn local_addr(&self) -> SocketAddr {
        self.addr
    }

    /// Returns true if connection is secure (tls enabled)
    pub fn secure(&self) -> bool {
        self.secure.as_ref().get()
    }

    /// Set secure flag
    pub fn set_secure(&self) {
        self.secure.as_ref().set(true)
    }
}

#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub enum Protocol {
    Unknown,
    Http10,
    Http11,
    Http2,
    Proto1,
    Proto2,
    Proto3,
    Proto4,
    Proto5,
    Proto6,
}

pub struct Io<T, P = ()> {
    io: T,
    proto: Protocol,
    params: P,
}

impl<T> Io<T, ()> {
    pub fn new(io: T) -> Self {
        Self {
            io,
            proto: Protocol::Unknown,
            params: (),
        }
    }
}

impl<T, P> Io<T, P> {
    /// Reconstruct from a parts.
    pub fn from_parts(io: T, params: P, proto: Protocol) -> Self {
        Self { io, params, proto }
    }

    /// Deconstruct into a parts.
    pub fn into_parts(self) -> (T, P, Protocol) {
        (self.io, self.params, self.proto)
    }

    /// Returns a shared reference to the underlying stream.
    pub fn get_ref(&self) -> &T {
        &self.io
    }

    /// Returns a mutable reference to the underlying stream.
    pub fn get_mut(&mut self) -> &mut T {
        &mut self.io
    }

    /// Get selected protocol
    pub fn protocol(&self) -> Protocol {
        self.proto
    }

    /// Return new Io object with new parameter.
    pub fn set<U>(self, params: U) -> Io<T, U> {
        Io {
            io: self.io,
            proto: self.proto,
            params: params,
        }
    }

    /// Maps an Io<_, P> to Io<_, U> by applying a function to a contained value.
    pub fn map<U, F>(self, op: F) -> Io<T, U>
    where
        F: FnOnce(P) -> U,
    {
        Io {
            io: self.io,
            proto: self.proto,
            params: op(self.params),
        }
    }
}

impl<T, P> std::ops::Deref for Io<T, P> {
    type Target = T;

    fn deref(&self) -> &T {
        &self.io
    }
}

impl<T, P> std::ops::DerefMut for Io<T, P> {
    fn deref_mut(&mut self) -> &mut T {
        &mut self.io
    }
}

impl<T: fmt::Debug, P> fmt::Debug for Io<T, P> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Io {{{:?}}}", self.io)
    }
}