Compare commits
8 commits
Author | SHA1 | Date | |
---|---|---|---|
51508c818a | |||
322179ea13 | |||
5134624b06 | |||
2b24a6def1 | |||
0158d7d7e0 | |||
560aa3d2af | |||
09a73d3ee5 | |||
11b201004a |
11 changed files with 53 additions and 33 deletions
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -101,7 +101,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "axum-controller"
|
name = "axum-controller"
|
||||||
version = "0.2.0"
|
version = "0.2.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"axum",
|
"axum",
|
||||||
"axum-controller-macros",
|
"axum-controller-macros",
|
||||||
|
@ -114,7 +114,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "axum-controller-macros"
|
name = "axum-controller-macros"
|
||||||
version = "0.2.0"
|
version = "0.2.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"axum",
|
"axum",
|
||||||
"prettyplease",
|
"prettyplease",
|
||||||
|
|
|
@ -6,10 +6,10 @@ resolver = "3"
|
||||||
authors = ["Tristan Druyen <ek36g2vcc@mozmail.com>"]
|
authors = ["Tristan Druyen <ek36g2vcc@mozmail.com>"]
|
||||||
categories = ["web-programming"]
|
categories = ["web-programming"]
|
||||||
description = "Helper macro's for better readability of axum handlers"
|
description = "Helper macro's for better readability of axum handlers"
|
||||||
edition = "2024"
|
edition = "2021"
|
||||||
homepage = "https://git.vlt81.de/vault81/axum-controller"
|
homepage = "https://git.vlt81.de/vault81/axum-controller"
|
||||||
keywords = ["axum", "controller", "macro", "routing"]
|
keywords = ["axum", "controller", "macro", "routing"]
|
||||||
license = "AGPL-3.0-or-later"
|
license = "AGPL-3.0-or-later"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
repository = "https://git.vlt81.de/vault81/axum-controller"
|
repository = "https://git.vlt81.de/vault81/axum-controller"
|
||||||
version = "0.2.0"
|
version = "0.3.0"
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
[](https://crates.io/crates/axum-controller)
|
[](https://crates.io/crates/axum-controller)
|
||||||
[](https://docs.rs/axum-controller)
|
[](https://docs.rs/axum-controller)
|
||||||
|

|
||||||
|
|
||||||
|
# DEPRECATED
|
||||||
|
|
||||||
|
This crate does not receive further development, it *might* work for your use case.
|
||||||
|
I've changed how I do routing & recommend checking out [axum-folder-router](https://crates.io/crates/axum-folder-router).
|
||||||
|
|
||||||
# Axum-Controller
|
# Axum-Controller
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
cargo-features = ["edition2024"]
|
|
||||||
[package]
|
[package]
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
categories.workspace = true
|
categories.workspace = true
|
||||||
|
@ -16,7 +15,7 @@ version.workspace = true
|
||||||
prettyplease = "0.2"
|
prettyplease = "0.2"
|
||||||
proc-macro2 = "1"
|
proc-macro2 = "1"
|
||||||
quote = "1"
|
quote = "1"
|
||||||
syn = { version = "2", features = ["parsing"] }
|
syn = { version = "2", features = ["extra-traits", "parsing", "printing"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
axum = { version = "0.8", features = [] }
|
axum = { version = "0.8", features = [] }
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream;
|
||||||
use proc_macro2::Ident;
|
use proc_macro2::Ident;
|
||||||
use syn::{
|
use syn::{
|
||||||
ItemImpl, MetaNameValue,
|
|
||||||
parse::{Parse, ParseStream},
|
parse::{Parse, ParseStream},
|
||||||
punctuated::Punctuated,
|
punctuated::Punctuated,
|
||||||
|
ItemImpl, MetaNameValue,
|
||||||
};
|
};
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate quote;
|
extern crate quote;
|
||||||
|
@ -130,8 +130,9 @@ pub fn controller(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(move |route| {
|
.map(move |route| {
|
||||||
quote! {
|
quote! {
|
||||||
.typed_route(#struct_name :: #route)
|
.typed_route(#struct_name :: #route)
|
||||||
}
|
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
@ -139,6 +140,23 @@ pub fn controller(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||||
.nest(#route, __nested_router)
|
.nest(#route, __nested_router)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let nested_router_qoute = quote! {
|
||||||
|
axum::Router::new()
|
||||||
|
#nesting_call
|
||||||
|
};
|
||||||
|
let unnested_router_quote = quote! {
|
||||||
|
__nested_router
|
||||||
|
};
|
||||||
|
let maybe_nesting_call = if let syn::Expr::Lit(lit) = route {
|
||||||
|
if lit.eq(&syn::parse_quote!("/")) {
|
||||||
|
unnested_router_quote
|
||||||
|
} else {
|
||||||
|
nested_router_qoute
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
nested_router_qoute
|
||||||
|
};
|
||||||
|
|
||||||
let middleware_calls = args
|
let middleware_calls = args
|
||||||
.middlewares
|
.middlewares
|
||||||
.clone()
|
.clone()
|
||||||
|
@ -151,15 +169,14 @@ pub fn controller(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||||
// one where it's #state
|
// one where it's #state
|
||||||
let from_controller_into_router_impl = quote! {
|
let from_controller_into_router_impl = quote! {
|
||||||
impl #struct_name {
|
impl #struct_name {
|
||||||
fn into_router(state: #state) -> axum::Router<#state> {
|
pub fn into_router(state: #state) -> axum::Router<#state> {
|
||||||
let __nested_router = axum::Router::new()
|
let __nested_router = axum::Router::new()
|
||||||
#(#route_calls)*
|
#(#route_calls)*
|
||||||
#(#middleware_calls)*
|
#(#middleware_calls)*
|
||||||
.with_state(state)
|
.with_state(state)
|
||||||
;
|
;
|
||||||
|
|
||||||
axum::Router::new()
|
#maybe_nesting_call
|
||||||
#nesting_call
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
cargo-features = ["edition2024"]
|
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
categories.workspace = true
|
categories.workspace = true
|
||||||
|
@ -14,11 +12,12 @@ repository.workspace = true
|
||||||
version.workspace = true
|
version.workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
axum-controller-macros = { path = "../axum-controller-macros", version = "0.2.0" }
|
axum-controller-macros = { path = "../axum-controller-macros", version = "0.3" }
|
||||||
axum-typed-routing = { path = "../vendor/axum-typed-routing", version = "0.2.0" }
|
axum-typed-routing = { path = "../vendor/axum-typed-routing", version = "0.2.0"}
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
axum = "0.8"
|
axum = "0.8"
|
||||||
|
axum-typed-routing = { path = "../vendor/axum-typed-routing", version = "0.2", features = []}
|
||||||
axum-test = { version = "17", features = [] }
|
axum-test = { version = "17", features = [] }
|
||||||
json = "0.12"
|
json = "0.12"
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
|
|
|
@ -15,5 +15,5 @@
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
pub use axum_controller_macros::controller;
|
pub use axum_controller_macros::controller;
|
||||||
pub use axum_typed_routing::TypedRouter;
|
|
||||||
pub use axum_typed_routing::route;
|
pub use axum_typed_routing::route;
|
||||||
|
pub use axum_typed_routing::TypedRouter;
|
||||||
|
|
|
@ -90,17 +90,17 @@
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
packages = {
|
packages = {
|
||||||
default = pkgs.callPackage ./package.nix { };
|
# default = pkgs.callPackage ./package.nix { };
|
||||||
};
|
};
|
||||||
}) // {
|
}) // {
|
||||||
hydraJobs =
|
hydraJobs =
|
||||||
let
|
let
|
||||||
system = "x86_64-linux";
|
system = "x86_64-linux";
|
||||||
packages = self.packages."${system}";
|
# packages = self.packages."${system}";
|
||||||
devShells = self.devShells."${system}";
|
devShells = self.devShells."${system}";
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
inherit packages devShells;
|
inherit devShells;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
5
vendor/axum-typed-routing-macros/src/lib.rs
vendored
5
vendor/axum-typed-routing-macros/src/lib.rs
vendored
|
@ -25,9 +25,9 @@ mod parsing;
|
||||||
/// ```
|
/// ```
|
||||||
/// - `METHOD` is the HTTP method, such as `GET`, `POST`, `PUT`, etc.
|
/// - `METHOD` is the HTTP method, such as `GET`, `POST`, `PUT`, etc.
|
||||||
/// - `PATH` is the path of the route, with optional path parameters and query parameters,
|
/// - `PATH` is the path of the route, with optional path parameters and query parameters,
|
||||||
/// e.g. `/item/:id?amount&offset`.
|
/// e.g. `/item/:id?amount&offset`.
|
||||||
/// - `STATE` is the type of axum-state, passed to the handler. This is optional, and if not
|
/// - `STATE` is the type of axum-state, passed to the handler. This is optional, and if not
|
||||||
/// specified, the state type is guessed based on the parameters of the handler.
|
/// specified, the state type is guessed based on the parameters of the handler.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -97,6 +97,7 @@ pub fn route(attr: TokenStream, mut item: TokenStream) -> TokenStream {
|
||||||
/// - `security` is the OpenApi security requirements.
|
/// - `security` is the OpenApi security requirements.
|
||||||
/// - `responses` are the OpenApi responses.
|
/// - `responses` are the OpenApi responses.
|
||||||
/// - `transform` is a closure that takes an `TransformOperation` and returns an `TransformOperation`.
|
/// - `transform` is a closure that takes an `TransformOperation` and returns an `TransformOperation`.
|
||||||
|
///
|
||||||
/// This may override the other options. (see the crate `aide` for more information).
|
/// This may override the other options. (see the crate `aide` for more information).
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
|
|
18
vendor/axum-typed-routing/examples/basic.rs
vendored
18
vendor/axum-typed-routing/examples/basic.rs
vendored
|
@ -1,20 +1,20 @@
|
||||||
#![allow(unused)]
|
#![allow(unused)]
|
||||||
use axum::extract::{State, Json};
|
use axum::extract::{Json, State};
|
||||||
use axum_typed_routing::{TypedRouter, route};
|
use axum_typed_routing::{route, TypedRouter};
|
||||||
|
|
||||||
#[route(GET "/item/:id?amount&offset")]
|
#[route(GET "/item/:id?amount&offset")]
|
||||||
async fn item_handler(
|
async fn item_handler(
|
||||||
id: u32,
|
id: u32,
|
||||||
amount: Option<u32>,
|
amount: Option<u32>,
|
||||||
offset: Option<u32>,
|
offset: Option<u32>,
|
||||||
State(state): State<String>,
|
State(state): State<String>,
|
||||||
Json(json): Json<u32>,
|
Json(json): Json<u32>,
|
||||||
) -> String {
|
) -> String {
|
||||||
todo!("handle request")
|
todo!("handle request")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let router: axum::Router = axum::Router::new()
|
let router: axum::Router = axum::Router::new()
|
||||||
.typed_route(item_handler)
|
.typed_route(item_handler)
|
||||||
.with_state("state".to_string());
|
.with_state("state".to_string());
|
||||||
}
|
}
|
||||||
|
|
2
vendor/axum-typed-routing/tests/main.rs
vendored
2
vendor/axum-typed-routing/tests/main.rs
vendored
|
@ -113,7 +113,6 @@ async fn test_wildcard() {
|
||||||
assert_eq!(response.json::<String>(), "foo/bar");
|
assert_eq!(response.json::<String>(), "foo/bar");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[cfg(feature = "aide")]
|
#[cfg(feature = "aide")]
|
||||||
mod aide_support {
|
mod aide_support {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -231,4 +230,3 @@ mod aide_support {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Reference in a new issue