Add macro to compile time check if a path is valid (#3288)

This commit is contained in:
Tomaz Canabrava
2025-03-27 19:54:49 +00:00
committed by GitHub
parent 62470bd503
commit ee4727b865
4 changed files with 53 additions and 0 deletions
Generated
+1
View File
@@ -394,6 +394,7 @@ dependencies = [
"pin-project-lite",
"prost",
"reqwest 0.12.12",
"rustversion",
"serde",
"serde_html_form",
"serde_json",
+1
View File
@@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning].
# Unreleased
- **fixed:** Fix a broken link in the documentation of `ErasedJson` ([#3186])
- **added:** Add `vpath!` for compile time path verification on static paths. ([#3288])
[#3186]: https://github.com/tokio-rs/axum/pull/3186
+1
View File
@@ -58,6 +58,7 @@ http-body = "1.0.0"
http-body-util = "0.1.0"
mime = "0.3"
pin-project-lite = "0.2"
rustversion = "1.0.9"
serde = "1.0"
tower = { version = "0.5.2", default-features = false, features = ["util"] }
tower-layer = "0.3"
+50
View File
@@ -25,6 +25,56 @@ pub use axum_macros::TypedPath;
#[cfg(feature = "typed-routing")]
pub use self::typed::{SecondElementIs, TypedPath};
// Validates a path at compile time, used with the vpath macro.
#[rustversion::since(1.80)]
#[doc(hidden)]
pub const fn __private_validate_static_path(path: &'static str) -> &'static str {
if path.is_empty() {
panic!("Paths must start with a `/`. Use \"/\" for root routes")
}
if path.as_bytes()[0] != b'/' {
panic!("Paths must start with /");
}
path
}
/// This macro aborts compilation if the path is invalid.
///
/// This example will fail to compile:
///
/// ```compile_fail
/// use axum::routing::{Router, get};
/// use axum_extra::vpath;
///
/// let router = axum::Router::<()>::new()
/// .route(vpath!("invalid_path"), get(root))
/// .to_owned();
///
/// async fn root() {}
/// ```
///
/// This one will compile without problems:
///
/// ```no_run
/// use axum::routing::{Router, get};
/// use axum_extra::vpath;
///
/// let router = axum::Router::<()>::new()
/// .route(vpath!("/valid_path"), get(root))
/// .to_owned();
///
/// async fn root() {}
/// ```
///
/// This macro is available only on rust versions 1.80 and above.
#[rustversion::since(1.80)]
#[macro_export]
macro_rules! vpath {
($e:expr) => {
const { $crate::routing::__private_validate_static_path($e) }
};
}
/// Extension trait that adds additional methods to [`Router`].
pub trait RouterExt<S>: sealed::Sealed {
/// Add a typed `GET` route to the router.