mirror of
https://github.com/tokio-rs/axum.git
synced 2025-04-26 13:56:22 +02:00
Easily convert typed paths into URIs (#790)
* Easily convert typed paths into URIs `#[derive(TypedPath)]` will now also generate `TryFrom<_> for Uri` for easily converting paths into URIs for use with `Redirect` and friends. Fixes https://github.com/tokio-rs/axum/issues/789 * Use a method on the `TypedPath` trait to convert to `Uri` * fix doc ref * Update changelogs
This commit is contained in:
parent
67c385cd2d
commit
da74084146
5 changed files with 45 additions and 2 deletions
axum-extra
axum-macros
|
@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning].
|
|||
|
||||
# Unreleased
|
||||
|
||||
- **added:** Add `TypedPath::to_uri` for converting the path into a `Uri` ([#790])
|
||||
- **added:** Add type safe routing. See `axum_extra::routing::typed` for more details ([#756])
|
||||
- **breaking:** `CachedRejection` has been removed ([#699])
|
||||
- **breaking:** `<Cached<T> as FromRequest>::Rejection` is now `T::Rejection`. ([#699])
|
||||
|
@ -16,6 +17,7 @@ and this project adheres to [Semantic Versioning].
|
|||
[#699]: https://github.com/tokio-rs/axum/pull/699
|
||||
[#719]: https://github.com/tokio-rs/axum/pull/719
|
||||
[#756]: https://github.com/tokio-rs/axum/pull/756
|
||||
[#790]: https://github.com/tokio-rs/axum/pull/790
|
||||
|
||||
# 0.1.2 (13. January, 2022)
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use super::sealed::Sealed;
|
||||
use http::Uri;
|
||||
|
||||
/// A type safe path.
|
||||
///
|
||||
|
@ -87,6 +88,8 @@ use super::sealed::Sealed;
|
|||
/// things, create links to known paths and have them verified statically. Note that the
|
||||
/// [`Display`] implementation for each field must return something that's compatible with its
|
||||
/// [`Deserialize`] implementation.
|
||||
/// - A [`TryFrom<_> for Uri`](std::convert::TryFrom) implementation to converting your paths into
|
||||
/// [`Uri`](axum::http::Uri).
|
||||
///
|
||||
/// Additionally the macro will verify the captures in the path matches the fields of the struct.
|
||||
/// For example this fails to compile since the struct doesn't have a `team_id` field:
|
||||
|
@ -148,6 +151,21 @@ use super::sealed::Sealed;
|
|||
pub trait TypedPath: std::fmt::Display {
|
||||
/// The path with optional captures such as `/users/:id`.
|
||||
const PATH: &'static str;
|
||||
|
||||
/// Convert the path into a `Uri`.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// The default implementation parses the required [`Display`] implemetation. If that fails it
|
||||
/// will panic.
|
||||
///
|
||||
/// Using `#[derive(TypedPath)]` will never result in a panic since it percent-encodes
|
||||
/// arguments.
|
||||
///
|
||||
/// [`Display`]: std::fmt::Display
|
||||
fn to_uri(&self) -> Uri {
|
||||
self.to_string().parse().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
/// Utility trait used with [`RouterExt`] to ensure the first element of a tuple type is a
|
||||
|
|
|
@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
# Unreleased
|
||||
|
||||
- Add `#[derive(TypedPath)]` for use with axum-extra's new "type safe" routing API ([#756])
|
||||
- **added:** Add `#[derive(TypedPath)]` for use with axum-extra's new "type safe" routing API ([#756])
|
||||
|
||||
# 0.1.0 (31. January, 2022)
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ pub(crate) fn expand(item_struct: ItemStruct) -> syn::Result<TokenStream> {
|
|||
let segments = parse_path(&path)?;
|
||||
expand_unnamed_fields(fields, ident, path, &segments)
|
||||
}
|
||||
syn::Fields::Unit => Ok(expand_unit_fields(ident, path)?),
|
||||
syn::Fields::Unit => expand_unit_fields(ident, path),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
23
axum-macros/tests/typed_path/pass/into_uri.rs
Normal file
23
axum-macros/tests/typed_path/pass/into_uri.rs
Normal file
|
@ -0,0 +1,23 @@
|
|||
use axum_extra::routing::TypedPath;
|
||||
use axum::http::Uri;
|
||||
use serde::Deserialize;
|
||||
|
||||
#[derive(TypedPath, Deserialize)]
|
||||
#[typed_path("/:id")]
|
||||
struct Named {
|
||||
id: u32,
|
||||
}
|
||||
|
||||
#[derive(TypedPath, Deserialize)]
|
||||
#[typed_path("/:id")]
|
||||
struct Unnamed(u32);
|
||||
|
||||
#[derive(TypedPath, Deserialize)]
|
||||
#[typed_path("/")]
|
||||
struct Unit;
|
||||
|
||||
fn main() {
|
||||
let _: Uri = Named { id: 1 }.to_uri();
|
||||
let _: Uri = Unnamed(1).to_uri();
|
||||
let _: Uri = Unit.to_uri();
|
||||
}
|
Loading…
Add table
Reference in a new issue