httpio 0.2.4

A transport-agnostic, async HTTP/1.1 client library for any runtime.
Documentation
use crate::structures::connection::http_connection::HttpConnection;
use crate::{
    structures::connection::http_connection_in_pool_state::HttpConnectionPoolState, utils::url::Url,
};
use futures::{AsyncBufRead, AsyncWrite};
use std::collections::HashMap;
use std::time::Duration;

const DEFAULT_IDLE_CONNECTION_TIMEOUT: Duration = Duration::from_secs(3 * 60);

pub type ReadDyn = Box<dyn AsyncBufRead + Unpin + 'static>;
pub type WriteDyn = Box<dyn AsyncWrite + Unpin + 'static>;

pub struct HttpConnectionPool {
    connections: HashMap<String, HttpConnectionPoolState<ReadDyn, WriteDyn>>,
    idle_connection_timeout: Duration,
}

impl HttpConnectionPool {
    pub fn new() -> Self {
        HttpConnectionPool {
            connections: HashMap::new(),
            idle_connection_timeout: DEFAULT_IDLE_CONNECTION_TIMEOUT,
        }
    }

    pub fn remove(&mut self, url: &Url) {
        self.connections.remove(&url.origin());
    }

    pub fn clear(&mut self) {
        self.connections.clear();
    }

    pub fn clear_stale(&mut self) {
        self.connections.retain(|_url, state| !state.stale());
    }

    pub fn contains(&mut self, host: &str) -> bool {
        self.connections.contains_key(host)
    }

    pub fn get(&mut self, host: &str) -> Option<HttpConnection<ReadDyn, WriteDyn>> {
        self.clear_stale();
        self.connections.remove(host).map(|state| state.connection)
    }

    pub fn put(&mut self, connection: HttpConnection<ReadDyn, WriteDyn>) {
        self.connections.insert(
            connection.host().to_owned(),
            HttpConnectionPoolState::new(connection, self.idle_connection_timeout),
        );
    }

    pub fn put_with_idle_timeout(
        &mut self,
        connection: HttpConnection<ReadDyn, WriteDyn>,
        idle_timeout: Duration,
    ) {
        self.connections.insert(
            connection.host().to_owned(),
            HttpConnectionPoolState::new(connection, idle_timeout),
        );
    }

    pub fn set_idle_timeout(&mut self, timeout: Duration) {
        self.idle_connection_timeout = timeout;
    }
}