Skip to content

Commit

Permalink
Enhance the tag & default tag support (#29)
Browse files Browse the repository at this point in the history
* Remove Tag and DefaultTag traits along with the need for those traits
* Remove useless assert struct
* Make path to be more neutral about its location -> allows path macro attributed methods within methods where as previously they needed to exists only in module level
  • Loading branch information
juhaku authored Feb 16, 2022
1 parent 7dba8c5 commit cddd480
Show file tree
Hide file tree
Showing 6 changed files with 23 additions and 58 deletions.
10 changes: 1 addition & 9 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,13 +235,5 @@ pub trait Component {
pub trait Path {
fn path() -> &'static str;

fn path_item() -> openapi::path::PathItem;
}

pub trait DefaultTag {
fn tag() -> &'static str;
}

pub trait Tag {
fn tag() -> &'static str;
fn path_item(defalt_tag: Option<&str>) -> openapi::path::PathItem;
}
13 changes: 6 additions & 7 deletions tests/path_derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,15 +123,14 @@ fn derive_path_with_all_info_success() {
}
}

test_api_fn! {
name: test_operation3,
module: derive_path_with_defaults,
operation: post,
path: "/foo/bar";
}

#[test]
fn derive_path_with_defaults_success() {
test_api_fn! {
name: test_operation3,
module: derive_path_with_defaults,
operation: post,
path: "/foo/bar";
}
let operation = test_api_fn_doc! {
derive_path_with_defaults::test_operation3,
operation: post,
Expand Down
2 changes: 0 additions & 2 deletions tests/utoipa_gen_test.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
#![cfg(feature = "actix_extras")]
#![allow(dead_code)]

use std::borrow::Cow;

use serde::{Deserialize, Serialize};
use utoipa::{Component, OpenApi};

Expand Down
6 changes: 5 additions & 1 deletion utoipa-gen/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
//! This is private utoipa codegen library and is not used alone
//! This is **private** utoipa codegen library and is not used alone
//!
//! The library contains macro implementations for utoipa library. Content
//! of the libarary documentation is available through **utoipa** library itself.
//! Consider browsing via the **utoipa** crate so all links will work correctly.

#![warn(missing_docs)]
#![warn(rustdoc::broken_intra_doc_links)]
Expand Down
26 changes: 5 additions & 21 deletions utoipa-gen/src/openapi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ impl ToTokens for OpenApi {
},
);

let path_items = impl_paths(&attributes.handlers, tokens);
let path_items = impl_paths(&attributes.handlers);

tokens.extend(quote! {
impl utoipa::OpenApi for #ident {
Expand All @@ -186,14 +186,14 @@ impl ToTokens for OpenApi {
}
}

fn impl_paths(handler_paths: &[ExprPath], quote: &mut TokenStream) -> TokenStream {
fn impl_paths(handler_paths: &[ExprPath]) -> TokenStream {
handler_paths.iter().fold(
quote! { utoipa::openapi::path::Paths::new() },
|mut paths, handler| {
let segments = handler.path.segments.iter().collect::<Vec<_>>();
let handler_fn_name = &*segments.last().unwrap().ident.to_string();

let tag = segments
let tag = &*segments
.iter()
.take(segments.len() - 1)
.map(|part| part.ident.to_string())
Expand All @@ -205,12 +205,7 @@ fn impl_paths(handler_paths: &[ExprPath], quote: &mut TokenStream) -> TokenStrea

let usage = syn::parse_str::<ExprPath>(
&vec![
if tag.starts_with("crate") {
None
} else {
Some("crate")
},
if tag.is_empty() { None } else { Some(&tag) },
if tag.is_empty() { None } else { Some(tag) },
Some(handler_ident_name),
]
.into_iter()
Expand All @@ -220,19 +215,8 @@ fn impl_paths(handler_paths: &[ExprPath], quote: &mut TokenStream) -> TokenStrea
)
.unwrap();

let assert_handler_ident = format_ident!("__assert_{}", handler_ident_name);
quote.extend(quote! {
#[allow(non_camel_case_types)]
struct #assert_handler_ident where #handler_ident : utoipa::Path;
use #usage;
impl utoipa::DefaultTag for #handler_ident {
fn tag() -> &'static str {
#tag
}
}
});
paths.extend(quote! {
.append(#handler_ident::path(), #handler_ident::path_item())
.append(#usage::path(), #usage::path_item(Some(#tag)))
});

paths
Expand Down
24 changes: 6 additions & 18 deletions utoipa-gen/src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ impl ToTokens for Path {
.as_ref()
.or(Some(&self.fn_name))
.expect_or_abort("expected to find operation id but was None");
let tag = self
let tag = &*self
.path_attr
.tag
.as_ref()
Expand All @@ -375,7 +375,6 @@ impl ToTokens for Path {
.expect_or_abort("expected to find path but was None");

let operation = Operation {
path_struct: &path_struct,
deprecated: &self.deprecated,
operation_id,
summary: self
Expand All @@ -392,22 +391,19 @@ impl ToTokens for Path {
#[allow(non_camel_case_types)]
pub struct #path_struct;

impl utoipa::Tag for #path_struct {
fn tag() -> &'static str {
#tag
}
}

impl utoipa::Path for #path_struct {
fn path() -> &'static str {
#path
}

fn path_item() -> utoipa::openapi::path::PathItem {
fn path_item(default_tag: Option<&str>) -> utoipa::openapi::path::PathItem {
use utoipa::openapi::ToArray;
utoipa::openapi::PathItem::new(
#path_operation,
#operation
#operation.with_tag(*[Some(#tag), default_tag, Some("crate")].iter()
.flatten()
.find(|t| !t.is_empty()).unwrap()
)
)
}
}
Expand All @@ -416,7 +412,6 @@ impl ToTokens for Path {
}

struct Operation<'a> {
path_struct: &'a Ident,
operation_id: &'a String,
summary: Option<&'a String>,
description: Option<&'a Vec<String>>,
Expand All @@ -441,15 +436,8 @@ impl ToTokens for Operation<'_> {
.with_responses(#responses)
});
// // .with_security()
let path_struct = self.path_struct;
let operation_id = self.operation_id;
tokens.extend(quote! {
.with_tag(
[<#path_struct as utoipa::Tag>::tag(),
<#path_struct as utoipa::DefaultTag>::tag()
]
.into_iter().find(|s| !s.is_empty()).unwrap_or_else(|| "crate")
)
.with_operation_id(
#operation_id
)
Expand Down

0 comments on commit cddd480

Please sign in to comment.