59 lines
1.8 KiB
Rust
59 lines
1.8 KiB
Rust
use axum::http::{uri, Uri};
|
|
|
|
pub fn uri_with_path(uri: &Uri, path: &str) -> Uri {
|
|
if path.starts_with('/') {
|
|
// 'path' is an root path, so let's just override the uri's path
|
|
return uri::Builder::new()
|
|
.scheme(uri.scheme_str().unwrap())
|
|
.authority(uri.authority().unwrap().as_str())
|
|
.path_and_query(path)
|
|
.build()
|
|
.unwrap();
|
|
}
|
|
|
|
// 'path' is a relative/local path, so let's combine it with the uri's path
|
|
let base_path = uri.path_and_query().map_or("/", |p| p.path());
|
|
|
|
if base_path.ends_with('/') {
|
|
return uri::Builder::new()
|
|
.scheme(uri.scheme_str().unwrap())
|
|
.authority(uri.authority().unwrap().as_str())
|
|
.path_and_query(format!("{base_path}{path}"))
|
|
.build()
|
|
.unwrap();
|
|
}
|
|
|
|
let (base, _) = base_path.rsplit_once('/').unwrap();
|
|
return uri::Builder::new()
|
|
.scheme(uri.scheme_str().unwrap())
|
|
.authority(uri.authority().unwrap().as_str())
|
|
.path_and_query(format!("{base}/{path}"))
|
|
.build()
|
|
.unwrap();
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use axum::http::Uri;
|
|
|
|
use crate::helpers::uri_with_path;
|
|
|
|
#[test]
|
|
fn uri_with_relative_path() {
|
|
let uri: Uri = "http://localhost/baba/".parse().unwrap();
|
|
assert_eq!(uri_with_path(&uri, "is/you").to_string(), "http://localhost/baba/is/you");
|
|
}
|
|
|
|
#[test]
|
|
fn uri_with_absolute_path() {
|
|
let uri: Uri = "http://localhost/baba/is/you".parse().unwrap();
|
|
assert_eq!(uri_with_path(&uri, "/keke/is/move").to_string(), "http://localhost/keke/is/move");
|
|
}
|
|
|
|
#[test]
|
|
fn uri_with_index_relative_path() {
|
|
let uri: Uri = "http://localhost/baba/is/you".parse().unwrap();
|
|
assert_eq!(uri_with_path(&uri, "happy").to_string(), "http://localhost/baba/is/happy");
|
|
}
|
|
}
|