Skip to content

Commit

Permalink
Add HTTP method macros to simplify path attribute macro
Browse files Browse the repository at this point in the history
- Added `get`, `post`, `put`, `delete`, `options`, `head`, `patch`,
`trace`, and `any` macros
  to simplify the `path` attribute configuration.
- These macros allow developers to define routes more concisely and
improve code readability.
  • Loading branch information
mokeyish committed Jan 18, 2025
1 parent 88a5842 commit 7752ae9
Show file tree
Hide file tree
Showing 2 changed files with 226 additions and 9 deletions.
28 changes: 19 additions & 9 deletions utoipa-axum/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,37 +202,47 @@ mod tests {
use tower::util::ServiceExt;
use utoipa::openapi::{Content, OpenApi, Ref, ResponseBuilder};
use utoipa::PartialSchema;
use utoipa::{delete, get, post};

#[utoipa::path(get, path = "/")]
// #[utoipa::path(get, path = "/")]
#[get("/")]
async fn root() {}

// --- user

#[utoipa::path(get, path = "/")]
// #[utoipa::path(get, path = "/")]
#[get("/")]
async fn get_user() {}

#[utoipa::path(post, path = "/")]
// #[utoipa::path(post, path = "/")]
#[post("/")]
async fn post_user() {}

#[utoipa::path(delete, path = "/")]
// #[utoipa::path(delete, path = "/")]
#[delete("/")]
async fn delete_user() {}

#[utoipa::path(get, path = "/search")]
// #[utoipa::path(get, path = "/search")]
#[get("/search")]
async fn search_user() {}

// --- customer

#[utoipa::path(get, path = "/")]
// #[utoipa::path(get, path = "/")]
#[get("/")]
async fn get_customer() {}

#[utoipa::path(post, path = "/")]
// #[utoipa::path(post, path = "/")]
#[post("/")]
async fn post_customer() {}

#[utoipa::path(delete, path = "/")]
// #[utoipa::path(delete, path = "/")]
#[delete("/")]
async fn delete_customer() {}

// test that with state handler compiles
#[utoipa::path(get, path = "/search")]
// #[utoipa::path(get, path = "/search")]
#[get("/search")]
async fn search_customer(State(_s): State<String>) {}

#[test]
Expand Down
207 changes: 207 additions & 0 deletions utoipa-gen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1957,6 +1957,213 @@ pub fn path(attr: TokenStream, item: TokenStream) -> TokenStream {
handler.to_token_stream().into()
}

/// HttpMethod Get
///
/// ```rust
/// use utoipa::get;
///
/// #[get("/")]
/// async fn root() {}
///
/// ```
/// Equivalent to:
/// ```rust
/// #[utoipa::path(get, path = "/")]
/// async fn root() {}
/// ```
#[proc_macro_attribute]
pub fn get(attr: TokenStream, item: TokenStream) -> TokenStream {
path(
format!("get, path={}", attr.to_string()).parse().unwrap(),
item,
)
}

/// HttpMethod Post
///
/// ```rust
/// use utoipa::post;
///
/// #[post("/")]
/// async fn root() {}
///
/// ```
/// Equivalent to:
/// ```rust
/// #[utoipa::path(post, path = "/")]
/// async fn root() {}
/// ```
#[proc_macro_attribute]
pub fn post(attr: TokenStream, item: TokenStream) -> TokenStream {
path(
format!("post, path={}", attr.to_string()).parse().unwrap(),
item,
)
}

/// HttpMethod Put
///
/// ```rust
/// use utoipa::put;
///
/// #[put("/")]
/// async fn root() {}
///
/// ```
/// Equivalent to:
/// ```rust
/// #[utoipa::path(put, path = "/")]
/// async fn root() {}
/// ```
#[proc_macro_attribute]
pub fn put(attr: TokenStream, item: TokenStream) -> TokenStream {
path(
format!("put, path={}", attr.to_string()).parse().unwrap(),
item,
)
}

/// HttpMethod Delete
///
/// ```rust
/// use utoipa::delete;
///
/// #[delete("/")]
/// async fn root() {}
///
/// ```
/// Equivalent to:
/// ```rust
/// #[utoipa::path(delete, path = "/")]
/// async fn root() {}
/// ```
#[proc_macro_attribute]
pub fn delete(attr: TokenStream, item: TokenStream) -> TokenStream {
path(
format!("delete, path={}", attr.to_string())
.parse()
.unwrap(),
item,
)
}

/// HttpMethod Options
///
/// ```rust
/// use utoipa::options;
///
/// #[options("/")]
/// async fn root() {}
///
/// ```
/// Equivalent to:
/// ```rust
/// #[utoipa::path(options, path = "/")]
/// async fn root() {}
/// ```
#[proc_macro_attribute]
pub fn options(attr: TokenStream, item: TokenStream) -> TokenStream {
path(
format!("options, path={}", attr.to_string())
.parse()
.unwrap(),
item,
)
}

/// HttpMethod Head
///
/// ```rust
/// use utoipa::head;
///
/// #[head("/")]
/// async fn root() {}
///
/// ```
/// Equivalent to:
/// ```rust
/// #[utoipa::path(head, path = "/")]
/// async fn root() {}
/// ```
#[proc_macro_attribute]
pub fn head(attr: TokenStream, item: TokenStream) -> TokenStream {
path(
format!("head, path={}", attr.to_string()).parse().unwrap(),
item,
)
}

/// HttpMethod Patch
///
/// ```rust
/// use utoipa::patch;
///
/// #[patch("/")]
/// async fn root() {}
///
/// ```
/// Equivalent to:
/// ```rust
/// #[utoipa::path(patch, path = "/")]
/// async fn root() {}
/// ```
#[proc_macro_attribute]
pub fn patch(attr: TokenStream, item: TokenStream) -> TokenStream {
path(
format!("patch, path={}", attr.to_string()).parse().unwrap(),
item,
)
}

/// HttpMethod Trace
///
/// ```rust
/// use utoipa::trace;
///
/// #[trace("/")]
/// async fn root() {}
///
/// ```
/// Equivalent to:
/// ```rust
/// #[utoipa::path(trace, path = "/")]
/// async fn root() {}
/// ```
#[proc_macro_attribute]
pub fn trace(attr: TokenStream, item: TokenStream) -> TokenStream {
path(
format!("trace, path={}", attr.to_string()).parse().unwrap(),
item,
)
}

/// HttpMethod Any
///
/// ```rust
/// use utoipa::any;
///
/// #[any("/")]
/// async fn root() {}
///
/// ```
/// Equivalent to:
/// ```rust
/// #[utoipa::path(method(get,post,put,delete,options,head,patch,trace), path = "/")]
/// async fn root() {}
/// ```
#[proc_macro_attribute]
pub fn any(attr: TokenStream, item: TokenStream) -> TokenStream {
path(
format!(
"method(get,post,put,delete,options,head,patch,trace), path={}",
attr.to_string()
)
.parse()
.unwrap(),
item,
)
}

#[proc_macro_derive(OpenApi, attributes(openapi))]
/// Generate OpenApi base object with defaults from
/// project settings.
Expand Down

0 comments on commit 7752ae9

Please sign in to comment.