cinema 0.1.0

HTTP record-replay proxy for Rust tests
Documentation
use crate::prelude::*;
use std::hash::Hash;
use std::sync::Arc;
use urlencoding::{decode, encode};

pub struct ProxyRoute {
    encoded: String,
    callback: Option<ProxyRouteCallback>,
}

pub type ProxyRouteCallback =
    Arc<dyn Fn(ProxyRouteCallbackPayload) -> CinemaResult<()> + Send + Sync>;

pub struct ProxyRouteCallbackPayload<'a> {
    pub request: &'a Request<Full<Bytes>>,
    pub status: StatusCode,
    pub headers: Option<&'a HeaderMap<HeaderValue>>,
    pub body: &'a Bytes,
}

impl ProxyRoute {
    pub fn new(origin: String, callback: Option<ProxyRouteCallback>) -> Self {
        let encoded = encode(&origin).into_owned();
        Self { encoded, callback }
    }

    pub fn origin(&self) -> String {
        decode(&self.encoded)
            .expect("Failed to decode URL we encoded earlier, something is really wrong")
            .into_owned()
    }

    pub fn proxy_url(&self, address: &ProxyAddress) -> String {
        format!("{}/{}", address.origin(), self.encoded)
    }

    pub fn forward_url(&self, path: &str) -> String {
        format!("{}/{}", self.origin(), path)
    }

    pub fn matching_path(&self, path: &str) -> Option<(String, Option<ProxyRouteCallback>)> {
        if let Some(path) = path.strip_prefix(&format!("/{}", self.encoded)) {
            Some((path.to_owned(), self.callback.clone()))
        } else {
            None
        }
    }
}

impl Hash for ProxyRoute {
    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
        self.encoded.hash(state);
    }
}

impl PartialEq for ProxyRoute {
    fn eq(&self, other: &Self) -> bool {
        self.encoded == other.encoded
    }
}

impl Eq for ProxyRoute {}