Support affixed typed path captures (#3782)

This commit is contained in:
Mochammad Farros Fatchur Roji
2026-06-10 21:24:35 +02:00
committed by GitHub
parent 42d6fdc80d
commit 5b52bcdcfa
2 changed files with 131 additions and 18 deletions
@@ -0,0 +1,79 @@
use axum_extra::routing::{RouterExt, TypedPath};
use serde::Deserialize;
#[derive(TypedPath, Deserialize)]
#[typed_path("/@{username}")]
struct PrefixedCapture {
username: String,
}
#[derive(TypedPath, Deserialize)]
#[typed_path("/files/{name}.json")]
struct SuffixedCapture {
name: String,
}
#[derive(TypedPath, Deserialize)]
#[typed_path("/users/{user_id}/teams/team-{team_id}")]
struct MixedCaptures {
user_id: u32,
team_id: u32,
}
#[derive(TypedPath, Deserialize)]
#[typed_path("/{{escaped_capture}}/{id}")]
struct EscapedBrace {
id: u32,
}
#[derive(TypedPath, Deserialize)]
#[typed_path("/@{username}")]
struct UnnamedPrefixedCapture(String);
fn main() {
_ = axum::Router::<()>::new().typed_get(|_: PrefixedCapture| async {});
_ = axum::Router::<()>::new().typed_get(|_: SuffixedCapture| async {});
_ = axum::Router::<()>::new().typed_get(|_: MixedCaptures| async {});
_ = axum::Router::<()>::new().typed_get(|_: EscapedBrace| async {});
assert_eq!(PrefixedCapture::PATH, "/@{username}");
assert_eq!(
format!(
"{}",
PrefixedCapture {
username: "alice".to_owned(),
}
),
"/@alice"
);
assert_eq!(SuffixedCapture::PATH, "/files/{name}.json");
assert_eq!(
format!(
"{}",
SuffixedCapture {
name: "report final".to_owned(),
}
),
"/files/report%20final.json"
);
assert_eq!(
format!(
"{}",
MixedCaptures {
user_id: 1,
team_id: 2,
}
),
"/users/1/teams/team-2"
);
assert_eq!(EscapedBrace::PATH, "/{{escaped_capture}}/{id}");
assert_eq!(format!("{}", EscapedBrace { id: 7 }), "/{escaped_capture}/7");
assert_eq!(
format!("{}", UnnamedPrefixedCapture("bob".to_owned())),
"/@bob"
);
}