mirror of
https://github.com/tokio-rs/axum.git
synced 2026-08-24 00:00:16 +02:00
Move axum-debug into axum-macros (#724)
* Move axum-debug into axum-macros * fix ref to axum-macros in changelog * Apply suggestions from code review Co-authored-by: Jonas Platte <[email protected]> Co-authored-by: Jonas Platte <[email protected]>
This commit is contained in:
co-authored by
Jonas Platte
parent
b1283e9708
commit
f6fc5ed80c
@@ -17,8 +17,3 @@ proc-macro = true
|
||||
proc-macro2 = "1.0"
|
||||
quote = "1.0"
|
||||
syn = { version = "1.0", features = ["full"] }
|
||||
|
||||
[dev-dependencies]
|
||||
axum = { path = "../axum", version = "0.4" }
|
||||
trybuild = "1.0"
|
||||
rustversion = "1.0"
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
This is a debugging crate that provides better error messages for [`axum`]
|
||||
framework.
|
||||
|
||||
**Note:** this crate is deprecated. Use [axum-macros] instead.
|
||||
|
||||
More information about this crate can be found in the [crate documentation][docs].
|
||||
|
||||
## Safety
|
||||
@@ -44,3 +46,4 @@ additional terms or conditions.
|
||||
[docs]: https://docs.rs/axum-debug
|
||||
[license]: /axum-debug/LICENSE
|
||||
[issue]: https://github.com/tokio-rs/axum/issues/new
|
||||
[axum-macros]: https://crates.io/crates/axum-macros
|
||||
|
||||
+7
-151
@@ -1,148 +1,19 @@
|
||||
//! This is a debugging crate that provides better error messages for [`axum`] framework.
|
||||
//!
|
||||
//! While using [`axum`], you can get long error messages for simple mistakes. For example:
|
||||
//! **Note:** this crate is deprecated. Use [axum-macros] instead.
|
||||
//!
|
||||
//! ```rust,compile_fail
|
||||
//! use axum::{routing::get, Router};
|
||||
//! [axum-macros]: https://crates.io/crates/axum-macros
|
||||
//!
|
||||
//! #[tokio::main]
|
||||
//! async fn main() {
|
||||
//! let app = Router::new().route("/", get(handler));
|
||||
//!
|
||||
//! axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
|
||||
//! .serve(app.into_make_service())
|
||||
//! .await
|
||||
//! .unwrap();
|
||||
//! }
|
||||
//!
|
||||
//! fn handler() -> &'static str {
|
||||
//! "Hello, world"
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! You will get a long error message about function not implementing [`Handler`] trait. But why
|
||||
//! does this function not implement it? To figure it out, the [`debug_handler`] macro can be used.
|
||||
//!
|
||||
//! ```rust,compile_fail
|
||||
//! # use axum::{routing::get, Router};
|
||||
//! # use axum_debug::debug_handler;
|
||||
//! #
|
||||
//! # #[tokio::main]
|
||||
//! # async fn main() {
|
||||
//! # let app = Router::new().route("/", get(handler));
|
||||
//! #
|
||||
//! # axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
|
||||
//! # .serve(app.into_make_service())
|
||||
//! # .await
|
||||
//! # .unwrap();
|
||||
//! # }
|
||||
//! #
|
||||
//! #[debug_handler]
|
||||
//! fn handler() -> &'static str {
|
||||
//! "Hello, world"
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! ```text
|
||||
//! error: handlers must be async functions
|
||||
//! --> main.rs:xx:1
|
||||
//! |
|
||||
//! xx | fn handler() -> &'static str {
|
||||
//! | ^^
|
||||
//! ```
|
||||
//!
|
||||
//! As the error message says, handler function needs to be async.
|
||||
//!
|
||||
//! ```rust,compile_fail
|
||||
//! use axum::{routing::get, Router};
|
||||
//! use axum_debug::debug_handler;
|
||||
//!
|
||||
//! #[tokio::main]
|
||||
//! async fn main() {
|
||||
//! let app = Router::new().route("/", get(handler));
|
||||
//!
|
||||
//! axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
|
||||
//! .serve(app.into_make_service())
|
||||
//! .await
|
||||
//! .unwrap();
|
||||
//! }
|
||||
//!
|
||||
//! #[debug_handler]
|
||||
//! async fn handler() -> &'static str {
|
||||
//! "Hello, world"
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! # Changing request body type
|
||||
//!
|
||||
//! By default `#[debug_handler]` assumes your request body type is `axum::body::Body`. This will
|
||||
//! work for most extractors but, for example, it wont work for `Request<axum::body::BoxBody>`,
|
||||
//! which only implements `FromRequest<BoxBody>` and _not_ `FromRequest<Body>`.
|
||||
//!
|
||||
//! To work around that the request body type can be customized like so:
|
||||
//!
|
||||
//! ```rust
|
||||
//! use axum::{body::BoxBody, http::Request};
|
||||
//! # use axum_debug::debug_handler;
|
||||
//!
|
||||
//! #[debug_handler(body = BoxBody)]
|
||||
//! async fn handler(request: Request<BoxBody>) {}
|
||||
//! ```
|
||||
//!
|
||||
//! # Performance
|
||||
//!
|
||||
//! Macros in this crate have no effect when using release profile. (eg. `cargo build --release`)
|
||||
//!
|
||||
//! [`axum`]: https://docs.rs/axum/0.3
|
||||
//! [`Handler`]: https://docs.rs/axum/0.3/axum/handler/trait.Handler.html
|
||||
//! [`debug_handler`]: macro@debug_handler
|
||||
|
||||
#![warn(
|
||||
clippy::all,
|
||||
clippy::dbg_macro,
|
||||
clippy::todo,
|
||||
clippy::empty_enum,
|
||||
clippy::enum_glob_use,
|
||||
clippy::mem_forget,
|
||||
clippy::unused_self,
|
||||
clippy::filter_map_next,
|
||||
clippy::needless_continue,
|
||||
clippy::needless_borrow,
|
||||
clippy::match_wildcard_for_single_variants,
|
||||
clippy::if_let_mutex,
|
||||
clippy::mismatched_target_os,
|
||||
clippy::await_holding_lock,
|
||||
clippy::match_on_vec_items,
|
||||
clippy::imprecise_flops,
|
||||
clippy::suboptimal_flops,
|
||||
clippy::lossy_float_literal,
|
||||
clippy::rest_pat_in_fully_bound_structs,
|
||||
clippy::fn_params_excessive_bools,
|
||||
clippy::exit,
|
||||
clippy::inefficient_to_string,
|
||||
clippy::linkedlist,
|
||||
clippy::macro_use_imports,
|
||||
clippy::option_option,
|
||||
clippy::verbose_file_reads,
|
||||
clippy::unnested_or_patterns,
|
||||
clippy::str_to_string,
|
||||
rust_2018_idioms,
|
||||
future_incompatible,
|
||||
nonstandard_style,
|
||||
missing_debug_implementations,
|
||||
missing_docs
|
||||
)]
|
||||
#![deny(unreachable_pub, private_in_public)]
|
||||
#![allow(elided_lifetimes_in_paths, clippy::type_complexity)]
|
||||
#![forbid(unsafe_code)]
|
||||
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||
#![cfg_attr(test, allow(clippy::float_cmp))]
|
||||
//! [`axum`]: https://docs.rs/axum/latest
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
|
||||
/// Generates better error messages when applied to a handler function.
|
||||
///
|
||||
/// See the [module docs](self) for more details.
|
||||
/// Note this crate is deprecated. Use [axum-macros] instead.
|
||||
///
|
||||
/// [axum-macros]: https://crates.io/crates/axum-macros
|
||||
#[deprecated(since = "0.3.3", note = "Use the axum-macros crate instead")]
|
||||
#[proc_macro_attribute]
|
||||
pub fn debug_handler(_attr: TokenStream, input: TokenStream) -> TokenStream {
|
||||
#[cfg(not(debug_assertions))]
|
||||
@@ -442,18 +313,3 @@ mod debug_handler {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ui() {
|
||||
#[rustversion::stable]
|
||||
fn go() {
|
||||
let t = trybuild::TestCases::new();
|
||||
t.compile_fail("tests/fail/*.rs");
|
||||
t.pass("tests/pass/*.rs");
|
||||
}
|
||||
|
||||
#[rustversion::not(stable)]
|
||||
fn go() {}
|
||||
|
||||
go();
|
||||
}
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
use axum_debug::debug_handler;
|
||||
|
||||
#[debug_handler]
|
||||
async fn handler(foo: bool) {}
|
||||
|
||||
fn main() {}
|
||||
@@ -1,7 +0,0 @@
|
||||
error[E0277]: the trait bound `bool: FromRequest<Body>` is not satisfied
|
||||
--> tests/fail/argument_not_extractor.rs:4:23
|
||||
|
|
||||
4 | async fn handler(foo: bool) {}
|
||||
| ^^^^ the trait `FromRequest<Body>` is not implemented for `bool`
|
||||
|
|
||||
= help: see issue #48214
|
||||
@@ -1,26 +0,0 @@
|
||||
use axum::{
|
||||
async_trait,
|
||||
extract::{FromRequest, RequestParts},
|
||||
};
|
||||
use axum_debug::debug_handler;
|
||||
|
||||
struct A;
|
||||
|
||||
#[async_trait]
|
||||
impl<B> FromRequest<B> for A
|
||||
where
|
||||
B: Send + 'static,
|
||||
{
|
||||
type Rejection = ();
|
||||
|
||||
async fn from_request(_req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
impl A {
|
||||
#[debug_handler]
|
||||
async fn handler(&mut self) {}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -1,5 +0,0 @@
|
||||
error: Handlers must only take owned values
|
||||
--> tests/fail/extract_self_mut.rs:23:22
|
||||
|
|
||||
23 | async fn handler(&mut self) {}
|
||||
| ^^^^^^^^^
|
||||
@@ -1,26 +0,0 @@
|
||||
use axum::{
|
||||
async_trait,
|
||||
extract::{FromRequest, RequestParts},
|
||||
};
|
||||
use axum_debug::debug_handler;
|
||||
|
||||
struct A;
|
||||
|
||||
#[async_trait]
|
||||
impl<B> FromRequest<B> for A
|
||||
where
|
||||
B: Send + 'static,
|
||||
{
|
||||
type Rejection = ();
|
||||
|
||||
async fn from_request(_req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
impl A {
|
||||
#[debug_handler]
|
||||
async fn handler(&self) {}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -1,5 +0,0 @@
|
||||
error: Handlers must only take owned values
|
||||
--> tests/fail/extract_self_ref.rs:23:22
|
||||
|
|
||||
23 | async fn handler(&self) {}
|
||||
| ^^^^^
|
||||
@@ -1,6 +0,0 @@
|
||||
use axum_debug::debug_handler;
|
||||
|
||||
#[debug_handler]
|
||||
async fn handler<T>() {}
|
||||
|
||||
fn main() {}
|
||||
@@ -1,13 +0,0 @@
|
||||
error: `#[axum_debug::debug_handler]` doesn't support generic functions
|
||||
--> tests/fail/generics.rs:4:17
|
||||
|
|
||||
4 | async fn handler<T>() {}
|
||||
| ^^^
|
||||
|
||||
error[E0282]: type annotations needed
|
||||
--> tests/fail/generics.rs:4:10
|
||||
|
|
||||
4 | async fn handler<T>() {}
|
||||
| ----- ^^^^^^^ cannot infer type for type parameter `T` declared on the function `handler`
|
||||
| |
|
||||
| consider giving `future` a type
|
||||
@@ -1,6 +0,0 @@
|
||||
use axum_debug::debug_handler;
|
||||
|
||||
#[debug_handler(foo)]
|
||||
async fn handler() {}
|
||||
|
||||
fn main() {}
|
||||
@@ -1,5 +0,0 @@
|
||||
error: unknown argument
|
||||
--> tests/fail/invalid_attrs.rs:3:17
|
||||
|
|
||||
3 | #[debug_handler(foo)]
|
||||
| ^^^
|
||||
@@ -1,6 +0,0 @@
|
||||
use axum_debug::debug_handler;
|
||||
|
||||
#[debug_handler]
|
||||
struct A;
|
||||
|
||||
fn main() {}
|
||||
@@ -1,5 +0,0 @@
|
||||
error: expected `fn`
|
||||
--> tests/fail/not_a_function.rs:4:1
|
||||
|
|
||||
4 | struct A;
|
||||
| ^^^^^^
|
||||
@@ -1,6 +0,0 @@
|
||||
use axum_debug::debug_handler;
|
||||
|
||||
#[debug_handler]
|
||||
fn handler() {}
|
||||
|
||||
fn main() {}
|
||||
@@ -1,5 +0,0 @@
|
||||
error: Handlers must be `async fn`s
|
||||
--> tests/fail/not_async.rs:4:1
|
||||
|
|
||||
4 | fn handler() {}
|
||||
| ^^
|
||||
@@ -1,9 +0,0 @@
|
||||
use axum_debug::debug_handler;
|
||||
|
||||
#[debug_handler]
|
||||
async fn handler() {
|
||||
let rc = std::rc::Rc::new(());
|
||||
async {}.await;
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -1,21 +0,0 @@
|
||||
error: future cannot be sent between threads safely
|
||||
--> tests/fail/not_send.rs:4:1
|
||||
|
|
||||
4 | async fn handler() {
|
||||
| ^^^^^ future returned by `handler` is not `Send`
|
||||
|
|
||||
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
|
||||
note: future is not `Send` as this value is used across an await
|
||||
--> tests/fail/not_send.rs:6:5
|
||||
|
|
||||
5 | let rc = std::rc::Rc::new(());
|
||||
| -- has type `Rc<()>` which is not `Send`
|
||||
6 | async {}.await;
|
||||
| ^^^^^^^^^^^^^^ await occurs here, with `rc` maybe used later
|
||||
7 | }
|
||||
| - `rc` is later dropped here
|
||||
note: required by a bound in `check`
|
||||
--> tests/fail/not_send.rs:4:1
|
||||
|
|
||||
4 | async fn handler() {
|
||||
| ^^^^^ required by this bound in `check`
|
||||
@@ -1,24 +0,0 @@
|
||||
use axum_debug::debug_handler;
|
||||
|
||||
#[debug_handler]
|
||||
async fn handler(
|
||||
e1: String,
|
||||
e2: String,
|
||||
e3: String,
|
||||
e4: String,
|
||||
e5: String,
|
||||
e6: String,
|
||||
e7: String,
|
||||
e8: String,
|
||||
e9: String,
|
||||
e10: String,
|
||||
e11: String,
|
||||
e12: String,
|
||||
e13: String,
|
||||
e14: String,
|
||||
e15: String,
|
||||
e16: String,
|
||||
e17: String,
|
||||
) {}
|
||||
|
||||
fn main() {}
|
||||
@@ -1,11 +0,0 @@
|
||||
error: Handlers cannot take more than 16 arguments. Use `(a, b): (ExtractorA, ExtractorA)` to further nest extractors
|
||||
--> tests/fail/too_many_extractors.rs:5:5
|
||||
|
|
||||
5 | / e1: String,
|
||||
6 | | e2: String,
|
||||
7 | | e3: String,
|
||||
8 | | e4: String,
|
||||
... |
|
||||
20 | | e16: String,
|
||||
21 | | e17: String,
|
||||
| |________________^
|
||||
@@ -1,8 +0,0 @@
|
||||
use axum_debug::debug_handler;
|
||||
|
||||
#[debug_handler]
|
||||
async fn handler() -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -1,11 +0,0 @@
|
||||
error[E0277]: the trait bound `bool: IntoResponse` is not satisfied
|
||||
--> tests/fail/wrong_return_type.rs:4:23
|
||||
|
|
||||
4 | async fn handler() -> bool {
|
||||
| ^^^^ the trait `IntoResponse` is not implemented for `bool`
|
||||
|
|
||||
note: required by a bound in `__axum_debug_check_handler_into_response::{closure#0}::check`
|
||||
--> tests/fail/wrong_return_type.rs:4:23
|
||||
|
|
||||
4 | async fn handler() -> bool {
|
||||
| ^^^^ required by this bound in `__axum_debug_check_handler_into_response::{closure#0}::check`
|
||||
@@ -1,10 +0,0 @@
|
||||
use axum_debug::debug_handler;
|
||||
|
||||
struct A;
|
||||
|
||||
impl A {
|
||||
#[debug_handler]
|
||||
async fn handler() {}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -1,10 +0,0 @@
|
||||
use axum::{body::BoxBody, http::Request};
|
||||
use axum_debug::debug_handler;
|
||||
|
||||
#[debug_handler(body = BoxBody)]
|
||||
async fn handler(_: Request<BoxBody>) {}
|
||||
|
||||
#[debug_handler(body = axum::body::BoxBody,)]
|
||||
async fn handler_with_trailing_comma_and_type_path(_: Request<axum::body::BoxBody>) {}
|
||||
|
||||
fn main() {}
|
||||
@@ -1,9 +0,0 @@
|
||||
use axum_debug::debug_handler;
|
||||
use std::future::Future;
|
||||
|
||||
#[debug_handler]
|
||||
fn handler() -> impl Future<Output = ()> {
|
||||
async {}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -1,9 +0,0 @@
|
||||
use axum_debug::debug_handler;
|
||||
use axum::response::IntoResponse;
|
||||
|
||||
#[debug_handler]
|
||||
async fn handler() -> impl IntoResponse {
|
||||
"hi!"
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -1,6 +0,0 @@
|
||||
use axum_debug::debug_handler;
|
||||
|
||||
#[debug_handler]
|
||||
async fn handler(_one: String, _two: String, _three: String) {}
|
||||
|
||||
fn main() {}
|
||||
@@ -1,9 +0,0 @@
|
||||
use axum_debug::debug_handler;
|
||||
|
||||
#[debug_handler]
|
||||
async fn handler(mut foo: String) -> String {
|
||||
foo += "bar";
|
||||
foo
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -1,9 +0,0 @@
|
||||
use axum_debug::debug_handler;
|
||||
use std::future::{Ready, ready};
|
||||
|
||||
#[debug_handler]
|
||||
fn handler() -> Ready<()> {
|
||||
ready(())
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -1,132 +0,0 @@
|
||||
use axum::{
|
||||
async_trait,
|
||||
extract::{FromRequest, RequestParts},
|
||||
response::IntoResponse,
|
||||
};
|
||||
use axum_debug::debug_handler;
|
||||
|
||||
fn main() {}
|
||||
|
||||
#[debug_handler]
|
||||
fn concrete_future() -> std::future::Ready<Result<impl IntoResponse, ()>> {
|
||||
std::future::ready(Ok(()))
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
fn impl_future() -> impl std::future::Future<Output = Result<impl IntoResponse, ()>> {
|
||||
std::future::ready(Ok(()))
|
||||
}
|
||||
|
||||
// === no args ===
|
||||
|
||||
#[debug_handler]
|
||||
async fn handler_no_arg_one() -> Result<impl IntoResponse, ()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
async fn handler_no_arg_two() -> Result<(), impl IntoResponse> {
|
||||
Err(())
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
async fn handler_no_arg_three() -> Result<impl IntoResponse, impl IntoResponse> {
|
||||
Ok::<_, ()>(())
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
async fn handler_no_arg_four() -> Result<impl IntoResponse, impl IntoResponse> {
|
||||
Err::<(), _>(())
|
||||
}
|
||||
|
||||
// === args ===
|
||||
|
||||
#[debug_handler]
|
||||
async fn handler_one(foo: String) -> Result<impl IntoResponse, ()> {
|
||||
dbg!(foo);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
async fn handler_two(foo: String) -> Result<(), impl IntoResponse> {
|
||||
dbg!(foo);
|
||||
Err(())
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
async fn handler_three(foo: String) -> Result<impl IntoResponse, impl IntoResponse> {
|
||||
dbg!(foo);
|
||||
Ok::<_, ()>(())
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
async fn handler_four(foo: String) -> Result<impl IntoResponse, impl IntoResponse> {
|
||||
dbg!(foo);
|
||||
Err::<(), _>(())
|
||||
}
|
||||
|
||||
// === no args with receiver ===
|
||||
|
||||
struct A;
|
||||
|
||||
impl A {
|
||||
#[debug_handler]
|
||||
async fn handler_no_arg_one(self) -> Result<impl IntoResponse, ()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
async fn handler_no_arg_two(self) -> Result<(), impl IntoResponse> {
|
||||
Err(())
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
async fn handler_no_arg_three(self) -> Result<impl IntoResponse, impl IntoResponse> {
|
||||
Ok::<_, ()>(())
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
async fn handler_no_arg_four(self) -> Result<impl IntoResponse, impl IntoResponse> {
|
||||
Err::<(), _>(())
|
||||
}
|
||||
}
|
||||
|
||||
// === args with receiver ===
|
||||
|
||||
impl A {
|
||||
#[debug_handler]
|
||||
async fn handler_one(self, foo: String) -> Result<impl IntoResponse, ()> {
|
||||
dbg!(foo);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
async fn handler_two(self, foo: String) -> Result<(), impl IntoResponse> {
|
||||
dbg!(foo);
|
||||
Err(())
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
async fn handler_three(self, foo: String) -> Result<impl IntoResponse, impl IntoResponse> {
|
||||
dbg!(foo);
|
||||
Ok::<_, ()>(())
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
async fn handler_four(self, foo: String) -> Result<impl IntoResponse, impl IntoResponse> {
|
||||
dbg!(foo);
|
||||
Err::<(), _>(())
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl<B> FromRequest<B> for A
|
||||
where
|
||||
B: Send + 'static,
|
||||
{
|
||||
type Rejection = ();
|
||||
|
||||
async fn from_request(_req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
use axum::response::{IntoResponse, Response};
|
||||
use axum_debug::debug_handler;
|
||||
|
||||
struct A;
|
||||
|
||||
impl A {
|
||||
#[debug_handler]
|
||||
async fn handler() -> Self {
|
||||
A
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoResponse for A {
|
||||
fn into_response(self) -> Response {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -1,26 +0,0 @@
|
||||
use axum::{
|
||||
async_trait,
|
||||
extract::{FromRequest, RequestParts},
|
||||
};
|
||||
use axum_debug::debug_handler;
|
||||
|
||||
struct A;
|
||||
|
||||
#[async_trait]
|
||||
impl<B> FromRequest<B> for A
|
||||
where
|
||||
B: Send + 'static,
|
||||
{
|
||||
type Rejection = ();
|
||||
|
||||
async fn from_request(_req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
impl A {
|
||||
#[debug_handler]
|
||||
async fn handler(self) {}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
Reference in New Issue
Block a user