use http::uri::PathAndQuery;
use http::Request;
use http::Uri;
use crate::error::Error;
pub trait PathReq {
fn path(&self) -> &str;
}
impl PathReq for &str {
#[inline]
fn path(&self) -> &str {
self
}
}
impl PathReq for String {
#[inline]
fn path(&self) -> &str {
self.as_str()
}
}
impl PathReq for PathAndQuery {
#[inline]
fn path(&self) -> &str {
self.as_str()
}
}
impl PathReq for Uri {
#[inline]
fn path(&self) -> &str {
Uri::path(self)
}
}
impl<T> PathReq for Request<T> {
#[inline]
fn path(&self) -> &str {
self.uri().path()
}
}
pub trait MethodReq {
fn method(&self) -> &http::Method;
}
impl<T> MethodReq for Request<T> {
#[inline]
fn method(&self) -> &http::Method {
http::Request::method(self)
}
}
pub trait RemovePrefix: Sized {
fn remove_prefix(self, prefix: &str) -> Result<Self, Error>;
}
impl RemovePrefix for String {
fn remove_prefix(self, prefix: &str) -> Result<String, Error> {
if prefix.contains('?') {
return Err(Error::Prefix);
};
self.as_str()
.strip_prefix(prefix)
.map(String::from)
.ok_or(Error::Prefix)
}
}
impl RemovePrefix for PathAndQuery {
fn remove_prefix(self, prefix: &str) -> Result<PathAndQuery, Error> {
if prefix.contains('?') {
return Err(Error::Prefix);
};
self.as_str()
.strip_prefix(prefix)
.and_then(|striped| striped.parse().ok())
.ok_or(Error::Prefix)
}
}
impl RemovePrefix for Uri {
fn remove_prefix(self, prefix: &str) -> Result<Uri, Error> {
if prefix.contains('?') {
return Err(Error::Prefix);
}
let mut parts = self.into_parts();
parts.path_and_query = match parts.path_and_query.take() {
None => return Err(Error::Prefix),
Some(p_and_q) => Some(p_and_q.remove_prefix(prefix)?),
};
Uri::from_parts(parts).map_err(|_| Error::Prefix)
}
}
impl<T> RemovePrefix for Request<T> {
#[inline]
fn remove_prefix(self, prefix: &str) -> Result<Request<T>, Error> {
if prefix.contains('?') {
return Err(Error::Prefix);
}
let (mut parts, body) = self.into_parts();
parts.uri = parts.uri.remove_prefix(prefix)?;
Ok(Request::from_parts(parts, body))
}
}
#[test]
fn test() {
let val = "/a/b".to_string();
let val = val.remove_prefix("/a").unwrap();
assert_eq!(val, "/b");
let val = PathAndQuery::from_static("/a/b");
let val = val.remove_prefix("/a").unwrap();
assert_eq!(val, "/b");
let val = Uri::from_static("/a/b");
let val = val.remove_prefix("/a").unwrap();
assert_eq!(val, "/b");
let val = Request::<()>::builder().uri("/a/b").body(()).unwrap();
let val = val.remove_prefix("/a").unwrap();
assert_eq!(val.uri(), "/b");
}