Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support arbitrary exprs in operation_id #472

Merged
merged 3 commits into from
Feb 2, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 14 additions & 10 deletions utoipa-gen/src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ use std::{io::Error, str::FromStr};

use proc_macro2::{Ident, Span, TokenStream as TokenStream2};
use proc_macro_error::abort;
use quote::{format_ident, quote, ToTokens};
use quote::{format_ident, quote, ToTokens, quote_spanned};
use syn::punctuated::Punctuated;
use syn::spanned::Spanned;
use syn::token::Paren;
use syn::{parenthesized, parse::Parse, Token};
use syn::{LitStr, Type};
use syn::{LitStr, Type, Expr, ExprLit, Lit};

use crate::component::{GenericType, TypeTree};
use crate::{parse_utils, Deprecated};
Expand Down Expand Up @@ -77,7 +78,7 @@ pub struct PathAttr<'p> {
request_body: Option<RequestBodyAttr<'p>>,
responses: Vec<Response<'p>>,
pub(super) path: Option<String>,
operation_id: Option<String>,
operation_id: Option<Expr>,
tag: Option<String>,
params: Vec<Parameter<'p>>,
security: Option<Array<'p, SecurityRequirementAttr>>,
Expand Down Expand Up @@ -183,7 +184,7 @@ impl Parse for PathAttr<'_> {

match attribute_name {
"operation_id" => {
path_attr.operation_id = Some(parse_utils::parse_next_literal_str(input)?);
path_attr.operation_id = Some(parse_utils::parse_next(input, || Expr::parse(input))?);
}
"path" => {
path_attr.path = Some(parse_utils::parse_next_literal_str(input)?);
Expand Down Expand Up @@ -362,11 +363,14 @@ impl<'p> Path<'p> {
impl<'p> ToTokens for Path<'p> {
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
let path_struct = format_ident!("{}{}", PATH_STRUCT_PREFIX, self.fn_name);
let operation_id: &String = self
let operation_id = self
.path_attr
.operation_id
.as_ref()
.or(Some(&self.fn_name))
.clone()
.or(Some(ExprLit {
attrs: vec![],
lit: Lit::Str(LitStr::new(&self.fn_name, Span::call_site()))
}.into()))
.unwrap_or_else(|| {
abort! {
Span::call_site(), "operation id is not defined for path";
Expand Down Expand Up @@ -469,7 +473,7 @@ impl<'p> ToTokens for Path<'p> {

#[cfg_attr(feature = "debug", derive(Debug))]
struct Operation<'a> {
operation_id: &'a String,
operation_id: Expr,
summary: Option<&'a String>,
description: Option<&'a Vec<String>>,
deprecated: &'a Option<bool>,
Expand Down Expand Up @@ -498,8 +502,8 @@ impl ToTokens for Operation<'_> {
.securities(Some(#security_requirements))
})
}
let operation_id = self.operation_id;
tokens.extend(quote! {
let operation_id = &self.operation_id;
tokens.extend(quote_spanned! { operation_id.span() =>
.operation_id(Some(#operation_id))
});

Expand Down
3 changes: 3 additions & 0 deletions utoipa-gen/tests/utoipa_gen_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,14 @@ struct Pet {
mod pet_api {
use super::*;

const ID: &str = "get_pet";

/// Get pet by id
///
/// Get pet from database by pet database id
#[utoipa::path(
get,
operation_id = ID,
path = "/pets/{id}",
responses(
(status = 200, description = "Pet found successfully", body = Pet),
Expand Down