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 {}