Skip to content

Instantly share code, notes, and snippets.

@mraerino
Created August 22, 2020 20:14
Show Gist options
  • Save mraerino/657ca7bd115b3bf85ea42420f9d2ade7 to your computer and use it in GitHub Desktop.
Save mraerino/657ca7bd115b3bf85ea42420f9d2ade7 to your computer and use it in GitHub Desktop.
use http::uri::{PathAndQuery, Uri};
use std::{convert::TryInto, path::PathBuf};
#[derive(Clone)]
pub struct MockedTransport<T: Clone> {
inner: T,
mock_url: Uri,
}
impl<T> MockedTransport<T>
where
T: Clone,
{
pub fn new(inner: T) -> Self {
Self::new_with_opts(inner, None::<&str>)
}
pub fn with_prefix<P: TryInto<PathAndQuery>>(inner: T, prefix: P) -> Self {
Self::new_with_opts(inner, Some(prefix))
}
fn new_with_opts<P: TryInto<PathAndQuery>>(inner: T, prefix: Option<P>) -> Self {
let mut mock_url_parts = mockito::server_url()
.parse::<Uri>()
.expect("invalid mock url")
.into_parts();
mock_url_parts.path_and_query =
prefix.map(|p| p.try_into().map_err(|_| ()).expect("invalid prefix"));
let mock_url = Uri::from_parts(mock_url_parts).expect("invalid url parts");
Self { inner, mock_url }
}
}
impl<T> tower_service::Service<hyper::Uri> for MockedTransport<T>
where
T: tower_service::Service<hyper::Uri> + Clone,
{
type Response = T::Response;
type Error = T::Error;
type Future = T::Future;
fn poll_ready(
&mut self,
cx: &mut std::task::Context<'_>,
) -> std::task::Poll<Result<(), Self::Error>> {
self.inner.poll_ready(cx)
}
fn call(&mut self, req: hyper::Uri) -> Self::Future {
let mut parts = self.mock_url.into_parts();
let path = parts
.path_and_query
.take()
.map_or_else(PathBuf::new, |pq| PathBuf::from(pq.path()))
.join(req.path())
.to_str()
.unwrap_or_default();
let path_and_query = if let Some(query) = req.query() {
format!("{}?{}", path, query).parse()
} else {
path.parse()
};
parts.path_and_query = path_and_query.ok();
let mocked_req = hyper::Uri::from_parts(parts).expect("invalid url");
self.inner.call(mocked_req)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment