mirror of
https://github.com/tokio-rs/axum.git
synced 2024-11-21 22:56:46 +01:00
Remove axum-debug code (#740)
This commit is contained in:
parent
9ddcd22031
commit
15914c4f15
7 changed files with 4 additions and 452 deletions
8
.github/workflows/CI.yml
vendored
8
.github/workflows/CI.yml
vendored
|
@ -103,14 +103,14 @@ jobs:
|
|||
-p axum-extra
|
||||
--all-features --all-targets
|
||||
# the compiler errors are different on 1.54 which makes
|
||||
# the trybuild tests in axum-debug fail, so just run the doc
|
||||
# the trybuild tests in axum-macros fail, so just run the doc
|
||||
# tests
|
||||
- name: Run axum-debug doc tests
|
||||
- name: Run axum-macros doc tests
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: test
|
||||
args: >
|
||||
-p axum-debug
|
||||
-p axum-macros
|
||||
--doc
|
||||
--all-features
|
||||
|
||||
|
@ -172,5 +172,5 @@ jobs:
|
|||
-p axum
|
||||
-p axum-core
|
||||
-p axum-extra
|
||||
-p axum-debug
|
||||
-p axum-macros
|
||||
--target armv5te-unknown-linux-musleabi
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
members = [
|
||||
"axum",
|
||||
"axum-core",
|
||||
"axum-debug",
|
||||
"axum-extra",
|
||||
"axum-macros",
|
||||
"examples/*",
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
# Unreleased
|
||||
|
||||
- None.
|
||||
|
||||
# 0.3.3 (31. January 2022)
|
||||
|
||||
- This crate is now deprecated. It continues to work but wont receive further
|
||||
updates. Use [axum-macros](https://crates.io/crates/axum-macros) instead.
|
||||
|
||||
# 0.3.2 (09. December 2021)
|
||||
|
||||
- Support checking `FromRequest` bounds for extractors whose request body is something else than
|
||||
`axum::body::Body`. Use `#[debug_handler(body = YourBodyType)]` to use a different request body
|
||||
type ([#595])
|
||||
|
||||
[#595]: https://github.com/tokio-rs/axum/pull/595
|
||||
|
||||
# 0.3.1 (06. December 2021)
|
||||
|
||||
- Fix `Result<impl IntoResponse, Error>` generating invalid code ([#588])
|
||||
|
||||
[#588]: https://github.com/tokio-rs/axum/pull/588
|
||||
|
||||
# 0.3.0 (03. December 2021)
|
||||
|
||||
- Update to axum 0.4. axum-debug will _not_ work with axum 0.3.x.
|
||||
|
||||
# 0.2.2 (22. October 2021)
|
||||
|
||||
- Fix regression causing errors when `#[debug_handler]` was used on functions with multiple
|
||||
extractors ([#552])
|
||||
|
||||
[#552]: https://github.com/tokio-rs/axum/pull/552
|
||||
|
||||
# 0.2.1 (19. October 2021)
|
||||
|
||||
- Make macro handle more cases such as mutable extractors and handlers taking
|
||||
`self` ([#518])
|
||||
|
||||
[#518]: https://github.com/tokio-rs/axum/pull/518
|
||||
|
||||
# 0.2.0 (13. October 2021)
|
||||
|
||||
- **breaking:** Removed `debug_router` macro.
|
||||
- **breaking:** Removed `check_service` function.
|
||||
- **breaking:** Removed `debug_service` function.
|
||||
|
||||
# 0.1.0 (6. October 2021)
|
||||
|
||||
- Initial release.
|
|
@ -1,19 +0,0 @@
|
|||
[package]
|
||||
categories = ["development-tools::debugging"]
|
||||
description = "Better error messages for axum framework."
|
||||
edition = "2018"
|
||||
homepage = "https://github.com/tokio-rs/axum"
|
||||
keywords = ["axum", "debugging", "debug"]
|
||||
license = "MIT"
|
||||
name = "axum-debug"
|
||||
readme = "README.md"
|
||||
repository = "https://github.com/tokio-rs/axum"
|
||||
version = "0.3.3"
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
proc-macro2 = "1.0"
|
||||
quote = "1.0"
|
||||
syn = { version = "1.0", features = ["full"] }
|
|
@ -1,7 +0,0 @@
|
|||
Copyright 2021 Axum Debug Contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -1,49 +0,0 @@
|
|||
# axum-debug
|
||||
|
||||
[![Build status](https://github.com/tokio-rs/axum/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/tokio-rs/axum-debug/actions/workflows/CI.yml)
|
||||
[![Crates.io](https://img.shields.io/crates/v/axum-debug)](https://crates.io/crates/axum-debug)
|
||||
[![Documentation](https://docs.rs/axum-debug/badge.svg)](https://docs.rs/axum-debug)
|
||||
|
||||
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
|
||||
|
||||
This crate uses `#![forbid(unsafe_code)]` to ensure everything is implemented in 100% safe Rust.
|
||||
|
||||
## Minimum supported Rust version
|
||||
|
||||
axum-debug's MSRV is 1.54.
|
||||
|
||||
## Getting Help
|
||||
|
||||
You're also welcome to ask in the [Discord channel][chat] or open an [issue]
|
||||
with your question.
|
||||
|
||||
## Contributing
|
||||
|
||||
:balloon: Thanks for your help improving the project! We are so happy to have
|
||||
you! We have a [contributing guide][contributing] to help you get involved in the
|
||||
`axum` project.
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the [MIT license][license].
|
||||
|
||||
### Contribution
|
||||
|
||||
Unless you explicitly state otherwise, any contribution intentionally submitted
|
||||
for inclusion in `axum` by you, shall be licensed as MIT, without any
|
||||
additional terms or conditions.
|
||||
|
||||
[`axum`]: https://crates.io/crates/axum
|
||||
[chat]: https://discord.gg/tokio
|
||||
[contributing]: /CONTRIBUTING.md
|
||||
[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
|
|
@ -1,315 +0,0 @@
|
|||
//! This is a debugging crate that provides better error messages for [`axum`] framework.
|
||||
//!
|
||||
//! **Note:** this crate is deprecated. Use [axum-macros] instead.
|
||||
//!
|
||||
//! [axum-macros]: https://crates.io/crates/axum-macros
|
||||
//!
|
||||
//! [`axum`]: https://docs.rs/axum/latest
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
|
||||
/// Generates better error messages when applied to a handler function.
|
||||
///
|
||||
/// 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))]
|
||||
return input;
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
return debug_handler::expand(_attr, input);
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
mod debug_handler {
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::{format_ident, quote, quote_spanned};
|
||||
use syn::{parse::Parse, spanned::Spanned, FnArg, ItemFn, Token, Type};
|
||||
|
||||
pub(crate) fn expand(
|
||||
attr: proc_macro::TokenStream,
|
||||
input: proc_macro::TokenStream,
|
||||
) -> proc_macro::TokenStream {
|
||||
match try_expand(attr.into(), input.into()) {
|
||||
Ok(tokens) => tokens.into(),
|
||||
Err(err) => err.into_compile_error().into(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn try_expand(attr: TokenStream, input: TokenStream) -> syn::Result<TokenStream> {
|
||||
let attr = syn::parse2::<Attrs>(attr)?;
|
||||
let item_fn = syn::parse2::<ItemFn>(input.clone())?;
|
||||
|
||||
check_extractor_count(&item_fn)?;
|
||||
|
||||
let check_inputs_impls_from_request =
|
||||
check_inputs_impls_from_request(&item_fn, &attr.body_ty);
|
||||
let check_output_impls_into_response = check_output_impls_into_response(&item_fn);
|
||||
let check_future_send = check_future_send(&item_fn);
|
||||
|
||||
let tokens = quote! {
|
||||
#input
|
||||
#check_inputs_impls_from_request
|
||||
#check_output_impls_into_response
|
||||
#check_future_send
|
||||
};
|
||||
|
||||
Ok(tokens)
|
||||
}
|
||||
|
||||
struct Attrs {
|
||||
body_ty: Type,
|
||||
}
|
||||
|
||||
impl Parse for Attrs {
|
||||
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
|
||||
let mut body_ty = None;
|
||||
|
||||
while !input.is_empty() {
|
||||
let ident = input.parse::<syn::Ident>()?;
|
||||
if ident == "body" {
|
||||
input.parse::<Token![=]>()?;
|
||||
body_ty = Some(input.parse()?);
|
||||
} else {
|
||||
return Err(syn::Error::new_spanned(ident, "unknown argument"));
|
||||
}
|
||||
|
||||
let _ = input.parse::<Token![,]>();
|
||||
}
|
||||
|
||||
let body_ty = body_ty.unwrap_or_else(|| syn::parse_quote!(axum::body::Body));
|
||||
|
||||
Ok(Self { body_ty })
|
||||
}
|
||||
}
|
||||
|
||||
fn check_extractor_count(item_fn: &ItemFn) -> syn::Result<()> {
|
||||
let max_extractors = 16;
|
||||
if item_fn.sig.inputs.len() <= max_extractors {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(syn::Error::new_spanned(
|
||||
&item_fn.sig.inputs,
|
||||
format!(
|
||||
"Handlers cannot take more than {} arguments. Use `(a, b): (ExtractorA, ExtractorA)` to further nest extractors",
|
||||
max_extractors,
|
||||
)
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn check_inputs_impls_from_request(item_fn: &ItemFn, body_ty: &Type) -> TokenStream {
|
||||
if !item_fn.sig.generics.params.is_empty() {
|
||||
return syn::Error::new_spanned(
|
||||
&item_fn.sig.generics,
|
||||
"`#[axum_debug::debug_handler]` doesn't support generic functions",
|
||||
)
|
||||
.into_compile_error();
|
||||
}
|
||||
|
||||
item_fn
|
||||
.sig
|
||||
.inputs
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(idx, arg)| {
|
||||
let (span, ty) = match arg {
|
||||
FnArg::Receiver(receiver) => {
|
||||
if receiver.reference.is_some() {
|
||||
return syn::Error::new_spanned(
|
||||
receiver,
|
||||
"Handlers must only take owned values",
|
||||
)
|
||||
.into_compile_error();
|
||||
}
|
||||
|
||||
let span = receiver.span();
|
||||
(span, syn::parse_quote!(Self))
|
||||
}
|
||||
FnArg::Typed(typed) => {
|
||||
let ty = &typed.ty;
|
||||
let span = ty.span();
|
||||
(span, ty.clone())
|
||||
}
|
||||
};
|
||||
|
||||
let name = format_ident!(
|
||||
"__axum_debug_check_{}_{}_from_request",
|
||||
item_fn.sig.ident,
|
||||
idx
|
||||
);
|
||||
quote_spanned! {span=>
|
||||
#[allow(warnings)]
|
||||
fn #name()
|
||||
where
|
||||
#ty: ::axum::extract::FromRequest<#body_ty> + Send,
|
||||
{}
|
||||
}
|
||||
})
|
||||
.collect::<TokenStream>()
|
||||
}
|
||||
|
||||
fn check_output_impls_into_response(item_fn: &ItemFn) -> TokenStream {
|
||||
let ty = match &item_fn.sig.output {
|
||||
syn::ReturnType::Default => return quote! {},
|
||||
syn::ReturnType::Type(_, ty) => ty,
|
||||
};
|
||||
let span = ty.span();
|
||||
|
||||
let declare_inputs = item_fn
|
||||
.sig
|
||||
.inputs
|
||||
.iter()
|
||||
.filter_map(|arg| match arg {
|
||||
FnArg::Receiver(_) => None,
|
||||
FnArg::Typed(pat_ty) => {
|
||||
let pat = &pat_ty.pat;
|
||||
let ty = &pat_ty.ty;
|
||||
Some(quote! {
|
||||
let #pat: #ty = panic!();
|
||||
})
|
||||
}
|
||||
})
|
||||
.collect::<TokenStream>();
|
||||
|
||||
let block = &item_fn.block;
|
||||
|
||||
let make_value_name = format_ident!(
|
||||
"__axum_debug_check_{}_into_response_make_value",
|
||||
item_fn.sig.ident
|
||||
);
|
||||
|
||||
let make = if item_fn.sig.asyncness.is_some() {
|
||||
quote_spanned! {span=>
|
||||
#[allow(warnings)]
|
||||
async fn #make_value_name() -> #ty {
|
||||
#declare_inputs
|
||||
#block
|
||||
}
|
||||
}
|
||||
} else {
|
||||
quote_spanned! {span=>
|
||||
#[allow(warnings)]
|
||||
fn #make_value_name() -> #ty {
|
||||
#declare_inputs
|
||||
#block
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let name = format_ident!("__axum_debug_check_{}_into_response", item_fn.sig.ident);
|
||||
|
||||
if let Some(receiver) = self_receiver(item_fn) {
|
||||
quote_spanned! {span=>
|
||||
#make
|
||||
|
||||
#[allow(warnings)]
|
||||
async fn #name() {
|
||||
let value = #receiver #make_value_name().await;
|
||||
fn check<T>(_: T)
|
||||
where T: ::axum::response::IntoResponse
|
||||
{}
|
||||
check(value);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
quote_spanned! {span=>
|
||||
#[allow(warnings)]
|
||||
async fn #name() {
|
||||
#make
|
||||
|
||||
let value = #make_value_name().await;
|
||||
|
||||
fn check<T>(_: T)
|
||||
where T: ::axum::response::IntoResponse
|
||||
{}
|
||||
|
||||
check(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_future_send(item_fn: &ItemFn) -> TokenStream {
|
||||
if item_fn.sig.asyncness.is_none() {
|
||||
match &item_fn.sig.output {
|
||||
syn::ReturnType::Default => {
|
||||
return syn::Error::new_spanned(
|
||||
&item_fn.sig.fn_token,
|
||||
"Handlers must be `async fn`s",
|
||||
)
|
||||
.into_compile_error();
|
||||
}
|
||||
syn::ReturnType::Type(_, ty) => ty,
|
||||
};
|
||||
}
|
||||
|
||||
let span = item_fn.span();
|
||||
|
||||
let handler_name = &item_fn.sig.ident;
|
||||
|
||||
let args = item_fn.sig.inputs.iter().map(|_| {
|
||||
quote_spanned! {span=> panic!() }
|
||||
});
|
||||
|
||||
let name = format_ident!("__axum_debug_check_{}_future", item_fn.sig.ident);
|
||||
|
||||
if let Some(receiver) = self_receiver(item_fn) {
|
||||
quote_spanned! {span=>
|
||||
#[allow(warnings)]
|
||||
fn #name() {
|
||||
let future = #receiver #handler_name(#(#args),*);
|
||||
fn check<T>(_: T)
|
||||
where T: ::std::future::Future + Send
|
||||
{}
|
||||
check(future);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
quote_spanned! {span=>
|
||||
#[allow(warnings)]
|
||||
fn #name() {
|
||||
#item_fn
|
||||
|
||||
let future = #handler_name(#(#args),*);
|
||||
fn check<T>(_: T)
|
||||
where T: ::std::future::Future + Send
|
||||
{}
|
||||
check(future);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn self_receiver(item_fn: &ItemFn) -> Option<TokenStream> {
|
||||
let takes_self = item_fn
|
||||
.sig
|
||||
.inputs
|
||||
.iter()
|
||||
.any(|arg| matches!(arg, syn::FnArg::Receiver(_)));
|
||||
if takes_self {
|
||||
return Some(quote! { Self:: });
|
||||
}
|
||||
|
||||
if let syn::ReturnType::Type(_, ty) = &item_fn.sig.output {
|
||||
if let syn::Type::Path(path) = &**ty {
|
||||
let segments = &path.path.segments;
|
||||
if segments.len() == 1 {
|
||||
if let Some(last) = segments.last() {
|
||||
match &last.arguments {
|
||||
syn::PathArguments::None if last.ident == "Self" => {
|
||||
return Some(quote! { Self:: });
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue