mirror of
https://github.com/tokio-rs/axum.git
synced 2026-08-27 00:00:24 +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:
@@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning].
|
|||||||
|
|
||||||
# Unreleased
|
# 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])
|
- **added:** Add type safe routing. See `axum_extra::routing::typed` for more details ([#756])
|
||||||
- **breaking:** `CachedRejection` has been removed ([#699])
|
- **breaking:** `CachedRejection` has been removed ([#699])
|
||||||
- **breaking:** `<Cached<T> as FromRequest>::Rejection` is now `T::Rejection`. ([#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
|
[#699]: https://github.com/tokio-rs/axum/pull/699
|
||||||
[#719]: https://github.com/tokio-rs/axum/pull/719
|
[#719]: https://github.com/tokio-rs/axum/pull/719
|
||||||
[#756]: https://github.com/tokio-rs/axum/pull/756
|
[#756]: https://github.com/tokio-rs/axum/pull/756
|
||||||
|
[#790]: https://github.com/tokio-rs/axum/pull/790
|
||||||
|
|
||||||
# 0.1.2 (13. January, 2022)
|
# 0.1.2 (13. January, 2022)
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use super::sealed::Sealed;
|
use super::sealed::Sealed;
|
||||||
|
use http::Uri;
|
||||||
|
|
||||||
/// A type safe path.
|
/// 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
|
/// 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
|
/// [`Display`] implementation for each field must return something that's compatible with its
|
||||||
/// [`Deserialize`] implementation.
|
/// [`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.
|
/// 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:
|
/// 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 {
|
pub trait TypedPath: std::fmt::Display {
|
||||||
/// The path with optional captures such as `/users/:id`.
|
/// The path with optional captures such as `/users/:id`.
|
||||||
const PATH: &'static str;
|
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
|
/// 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
|
# 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)
|
# 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)?;
|
let segments = parse_path(&path)?;
|
||||||
expand_unnamed_fields(fields, ident, path, &segments)
|
expand_unnamed_fields(fields, ident, path, &segments)
|
||||||
}
|
}
|
||||||
syn::Fields::Unit => Ok(expand_unit_fields(ident, path)?),
|
syn::Fields::Unit => expand_unit_fields(ident, path),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user