From 4858484cbdf5d9dec732118fcbaa399d43297086 Mon Sep 17 00:00:00 2001 From: Chrislearn Young Date: Wed, 5 Jun 2024 13:00:42 +0800 Subject: [PATCH] Fix feature config error (#802) * Fix feature config error in extra * Fix feature setting error --- crates/extra/src/lib.rs | 10 ----- crates/oapi-macros/src/bound.rs | 4 -- crates/oapi-macros/src/cfg.rs | 12 ++++++ crates/oapi-macros/src/feature/mod.rs | 22 +++++----- crates/oapi-macros/src/lib.rs | 32 +++++++++++++- crates/oapi-macros/src/schema/enum_variant.rs | 43 ++++++++++--------- .../oapi-macros/src/security_requirement.rs | 1 - crates/oapi/docs/derive_to_schema.md | 16 +++---- crates/oapi/src/openapi/mod.rs | 11 ++--- crates/oapi/src/openapi/schema/mod.rs | 9 ++-- crates/salvo/src/lib.rs | 2 +- examples/affix/src/main.rs | 2 +- 12 files changed, 97 insertions(+), 67 deletions(-) create mode 100644 crates/oapi-macros/src/cfg.rs diff --git a/crates/extra/src/lib.rs b/crates/extra/src/lib.rs index 7d26ddd98..e518b200a 100644 --- a/crates/extra/src/lib.rs +++ b/crates/extra/src/lib.rs @@ -43,21 +43,11 @@ cfg_feature! { #![feature = "force-https"] pub mod force_https; } - -cfg_feature! { - #![feature = "jwt-auth"] - pub mod jwt_auth; -} - cfg_feature! { #![feature = "catch-panic"] pub mod catch_panic; } -cfg_feature! { - #![feature = "compression"] - pub mod compression; -} cfg_feature! { #![feature = "logging"] pub mod logging; diff --git a/crates/oapi-macros/src/bound.rs b/crates/oapi-macros/src/bound.rs index 5b556dc9d..f1346c008 100644 --- a/crates/oapi-macros/src/bound.rs +++ b/crates/oapi-macros/src/bound.rs @@ -103,10 +103,8 @@ pub(crate) fn with_bound( } // Everything below is simply traversing the syntax tree. - fn visit_type(&mut self, ty: &'ast syn::Type) { match ty { - #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))] syn::Type::Array(ty) => self.visit_type(&ty.elem), syn::Type::BareFn(ty) => { for arg in &ty.inputs { @@ -158,7 +156,6 @@ pub(crate) fn with_bound( syn::PathArguments::AngleBracketed(arguments) => { for arg in &arguments.args { match arg { - #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))] syn::GenericArgument::Type(arg) => self.visit_type(arg), syn::GenericArgument::AssocType(arg) => self.visit_type(&arg.ty), syn::GenericArgument::Lifetime(_) @@ -187,7 +184,6 @@ pub(crate) fn with_bound( fn visit_type_param_bound(&mut self, bound: &'ast syn::TypeParamBound) { match bound { - #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))] syn::TypeParamBound::Trait(bound) => self.visit_path(&bound.path), syn::TypeParamBound::Lifetime(_) | syn::TypeParamBound::Verbatim(_) => {} _ => {} diff --git a/crates/oapi-macros/src/cfg.rs b/crates/oapi-macros/src/cfg.rs new file mode 100644 index 000000000..f7b45a235 --- /dev/null +++ b/crates/oapi-macros/src/cfg.rs @@ -0,0 +1,12 @@ +macro_rules! cfg_feature { + ( + #![$meta:meta] + $($item:item)* + ) => { + $( + #[cfg($meta)] + #[cfg_attr(docsrs, doc(cfg($meta)))] + $item + )* + } +} diff --git a/crates/oapi-macros/src/feature/mod.rs b/crates/oapi-macros/src/feature/mod.rs index 3b4863f8e..37a95e3f0 100644 --- a/crates/oapi-macros/src/feature/mod.rs +++ b/crates/oapi-macros/src/feature/mod.rs @@ -381,17 +381,17 @@ impl Validator for IsString<'_> { } } -pub(crate) struct IsInteger<'a>(&'a SchemaType<'a>); - -impl Validator for IsInteger<'_> { - fn is_valid(&self) -> Result<(), &'static str> { - if self.0.is_integer() { - Ok(()) - } else { - Err("can only be used with `integer` type") - } - } -} +// pub(crate) struct IsInteger<'a>(&'a SchemaType<'a>); + +// impl Validator for IsInteger<'_> { +// fn is_valid(&self) -> Result<(), &'static str> { +// if self.0.is_integer() { +// Ok(()) +// } else { +// Err("can only be used with `integer` type") +// } +// } +// } pub(crate) struct IsVec<'a>(&'a TypeTree<'a>); diff --git a/crates/oapi-macros/src/lib.rs b/crates/oapi-macros/src/lib.rs index ec4fb21b5..d2201842c 100644 --- a/crates/oapi-macros/src/lib.rs +++ b/crates/oapi-macros/src/lib.rs @@ -14,6 +14,8 @@ use syn::parse::{Parse, ParseStream}; use syn::token::Bracket; use syn::{bracketed, parse_macro_input, Ident, Item, Token}; +#[macro_use] +mod cfg; mod attribute; pub(crate) mod bound; mod component; @@ -230,10 +232,17 @@ mod tests { #[test] fn test_to_schema_struct() { let input = quote! { + /// This is user. + /// + /// This is user description. #[derive(ToSchema)] struct User{ + #[salvo(schema(example = "chris", min_length = 1, max_length = 100, required))] name: String, + #[salvo(schema(example = 16, default = 0, maximum=100, minimum=0,format = "int32"))] age: i32, + #[deprecated = "There is deprecated"] + high: u32, } }; assert_eq!( @@ -249,7 +258,11 @@ mod tests { let schema = salvo::oapi::Object::new() .property( "name", - salvo::oapi::Object::new().schema_type(salvo::oapi::SchemaType::String) + salvo::oapi::Object::new() + .schema_type(salvo::oapi::SchemaType::String) + .example(salvo::oapi::__private::serde_json::json!("chris")) + .min_length(1usize) + .max_length(100usize) ) .required("name") .property( @@ -257,8 +270,23 @@ mod tests { salvo::oapi::Object::new() .schema_type(salvo::oapi::SchemaType::Integer) .format(salvo::oapi::SchemaFormat::KnownFormat(salvo::oapi::KnownFormat::Int32)) + .example(salvo::oapi::__private::serde_json::json!(16)) + .default_value(salvo::oapi::__private::serde_json::json!(0)) + .maximum(100f64) + .minimum(0f64) + .format(salvo::oapi::SchemaFormat::Custom(String::from("int32"))) + ) + .required("age") + .property( + "high", + salvo::oapi::Object::new() + .schema_type(salvo::oapi::SchemaType::Integer) + .format(salvo::oapi::SchemaFormat::KnownFormat(salvo::oapi::KnownFormat::Int32)) + .deprecated(salvo::oapi::Deprecated::True) + .minimum(0f64) ) - .required("age"); + .required("high") + .description("This is user.\n\nThis is user description."); components.schemas.insert(name, schema); } ref_or diff --git a/crates/oapi-macros/src/schema/enum_variant.rs b/crates/oapi-macros/src/schema/enum_variant.rs index 7a0f13618..d477831eb 100644 --- a/crates/oapi-macros/src/schema/enum_variant.rs +++ b/crates/oapi-macros/src/schema/enum_variant.rs @@ -3,7 +3,7 @@ use std::marker::PhantomData; use proc_macro2::TokenStream; use quote::{quote, ToTokens}; -use syn::{parse_quote, TypePath}; +use syn::parse_quote; use crate::feature::Feature; use crate::schema_type::SchemaType; @@ -38,27 +38,30 @@ where } } -pub(crate) struct ReprVariant<'r, T: ToTokens> { - pub(crate) value: T, - pub(crate) type_path: &'r TypePath, -} - -impl<'r, T> Variant for ReprVariant<'r, T> -where - T: ToTokens, -{ - fn to_tokens(&self) -> TokenStream { - self.value.to_token_stream() +cfg_feature! { + #![feature ="repr"] + pub(crate) struct ReprVariant<'r, T: ToTokens> { + pub(crate) value: T, + pub(crate) type_path: &'r syn::TypePath, } - fn get_type(&self) -> (TokenStream, TokenStream) { - ( - match SchemaType(&self.type_path.path).try_to_token_stream() { - Ok(stream) => stream, - Err(diag) => diag.emit_as_item_tokens(), - }, - self.type_path.to_token_stream(), - ) + impl<'r, T> Variant for ReprVariant<'r, T> + where + T: ToTokens, + { + fn to_tokens(&self) -> TokenStream { + self.value.to_token_stream() + } + + fn get_type(&self) -> (TokenStream, TokenStream) { + ( + match SchemaType(&self.type_path.path).try_to_token_stream() { + Ok(stream) => stream, + Err(diag) => diag.emit_as_item_tokens(), + }, + self.type_path.to_token_stream(), + ) + } } } diff --git a/crates/oapi-macros/src/security_requirement.rs b/crates/oapi-macros/src/security_requirement.rs index 34b543cf8..5d35b53a8 100644 --- a/crates/oapi-macros/src/security_requirement.rs +++ b/crates/oapi-macros/src/security_requirement.rs @@ -16,7 +16,6 @@ pub(crate) struct SecurityRequirementsAttrItem { } #[derive(Default, Debug)] -#[cfg_attr(feature = "debug", derive(Debug))] pub(crate) struct SecurityRequirementsAttr(Punctuated); impl Parse for SecurityRequirementsAttr { diff --git a/crates/oapi/docs/derive_to_schema.md b/crates/oapi/docs/derive_to_schema.md index e108b406b..acb568a81 100644 --- a/crates/oapi/docs/derive_to_schema.md +++ b/crates/oapi/docs/derive_to_schema.md @@ -37,8 +37,8 @@ struct Pet { * `rename_all = ...` Supports same syntax as _serde_ _`rename_all`_ attribute. Will rename all fields of the structs accordingly. If both _serde_ `rename_all` and _schema_ _`rename_all`_ are defined __serde__ will take precedence. -* `symbol = ...` Literal string value. Can be used to define alternative path and name for the schema what will be used in - the OpenAPI. E.g _`symbol = "path::to::Pet"`_. This would make the schema appear in the generated +* `name = ...` Literal string value. Can be used to define alternative path and name for the schema what will be used in + the OpenAPI. E.g _`name = "path::to::Pet"`_. This would make the schema appear in the generated OpenAPI spec as _`path.to.Pet`_. * `default` Can be used to populate default values on all fields using the struct's [`Default`](std::default::Default) implementation. @@ -57,8 +57,8 @@ struct Pet { * `rename_all = ...` Supports same syntax as _serde_ _`rename_all`_ attribute. Will rename all variants of the enum accordingly. If both _serde_ `rename_all` and _schema_ _`rename_all`_ are defined __serde__ will take precedence. -* `symbol = ...` Literal string value. Can be used to define alternative path and name for the schema what will be used in - the OpenAPI. E.g _`symbol = "path::to::Pet"`_. This would make the schema appear in the generated +* `name = ...` Literal string value. Can be used to define alternative path and name for the schema what will be used in + the OpenAPI. E.g _`name = "path::to::Pet"`_. This would make the schema appear in the generated OpenAPI spec as _`path.to.Pet`_. * `deprecated` Can be used to mark all fields as deprecated in the generated OpenAPI spec but not in the code. If you'd like to mark the fields as deprecated in the code as well use @@ -90,8 +90,8 @@ _`rename`_ and _schema_ _`rename`_ are defined __serde__ will take precedence. any third-party types are used which are not [`ToSchema`][to_schema]s nor [`primitive` types][primitive]. Value can be any Rust type what normally could be used to serialize to JSON or custom type such as _`Object`_. _`Object`_ will be rendered as generic OpenAPI object _(`type: object`)_. -* `symbol = ...` Literal string value. Can be used to define alternative path and name for the schema what will be used in - the OpenAPI. E.g _`symbol = "path::to::Pet"`_. This would make the schema appear in the generated +* `name = ...` Literal string value. Can be used to define alternative path and name for the schema what will be used in + the OpenAPI. E.g _`name = "path::to::Pet"`_. This would make the schema appear in the generated OpenAPI spec as _`path.to.Pet`_. * `deprecated` Can be used to mark all fields as deprecated in the generated OpenAPI spec but not in the code. If you'd like to mark the fields as deprecated in the code as well use @@ -257,8 +257,8 @@ their numeric value. * `example = ...` Can be method reference or _`json!(...)`_. * `default = ...` Can be method reference or _`json!(...)`_. -* `symbol = ...` Literal string value. Can be used to define alternative path and name for the schema what will be used in - the OpenAPI. E.g _`symbol = "path::to::Pet"`_. This would make the schema appear in the generated +* `name = ...` Literal string value. Can be used to define alternative path and name for the schema what will be used in + the OpenAPI. E.g _`name = "path::to::Pet"`_. This would make the schema appear in the generated OpenAPI spec as _`path.to.Pet`_. _**Create enum with numeric values.**_ diff --git a/crates/oapi/src/openapi/mod.rs b/crates/oapi/src/openapi/mod.rs index 9dab1a4d5..f2a6f43db 100644 --- a/crates/oapi/src/openapi/mod.rs +++ b/crates/oapi/src/openapi/mod.rs @@ -153,11 +153,12 @@ impl OpenApi { serde_json::to_string_pretty(self) } - /// Converts this [`OpenApi`] to YAML String. This method essentially calls [`serde_yaml::to_string`] method. - #[cfg(feature = "yaml")] - #[cfg_attr(doc_cfg, doc(cfg(feature = "yaml")))] - pub fn to_yaml(&self) -> Result { - serde_yaml::to_string(self) + cfg_feature! { + #![feature ="yaml"] + /// Converts this [`OpenApi`] to YAML String. This method essentially calls [`serde_yaml::to_string`] method. + pub fn to_yaml(&self) -> Result { + serde_yaml::to_string(self) + } } /// Merge `other` [`OpenApi`] consuming it and resuming it's content. diff --git a/crates/oapi/src/openapi/schema/mod.rs b/crates/oapi/src/openapi/schema/mod.rs index 7bafd7acf..eb6ee00ef 100644 --- a/crates/oapi/src/openapi/schema/mod.rs +++ b/crates/oapi/src/openapi/schema/mod.rs @@ -379,25 +379,26 @@ pub enum KnownFormat { /// /// **decimal** feature need to be enabled. #[cfg(any(feature = "decimal", feature = "decimal-float"))] - #[cfg_attr(doc_cfg, doc(cfg(any(feature = "decimal", feature = "decimal-float"))))] + #[cfg_attr(docsrs, doc(cfg(any(feature = "decimal", feature = "decimal-float"))))] Decimal, /// Used with [`String`] values to indicate value is in Url format. /// /// **url** feature need to be enabled. #[cfg(feature = "url")] - #[cfg_attr(doc_cfg, doc(cfg(feature = "url")))] + #[cfg_attr(docsrs, doc(cfg(feature = "url")))] Url, /// Used with [`String`] values to indicate value is in ULID format. /// /// **ulid** feature need to be enabled. #[cfg(feature = "ulid")] - #[cfg_attr(doc_cfg, doc(cfg(feature = "ulid")))] + #[cfg_attr(docsrs, doc(cfg(feature = "ulid")))] Ulid, + /// Used with [`String`] values to indicate value is in UUID format. /// /// **uuid** feature need to be enabled. #[cfg(feature = "uuid")] - #[cfg_attr(doc_cfg, doc(cfg(feature = "uuid")))] + #[cfg_attr(docsrs, doc(cfg(feature = "uuid")))] Uuid, } diff --git a/crates/salvo/src/lib.rs b/crates/salvo/src/lib.rs index fd61eb237..066d83379 100644 --- a/crates/salvo/src/lib.rs +++ b/crates/salvo/src/lib.rs @@ -107,7 +107,7 @@ cfg_feature! { pub use salvo_extra::websocket; } cfg_feature! { - #![feature ="request_id"] + #![feature ="request-id"] // #[doc(no_inline)] pub use salvo_extra::request_id; } diff --git a/examples/affix/src/main.rs b/examples/affix/src/main.rs index e0bb6ca42..2081cd0c0 100644 --- a/examples/affix/src/main.rs +++ b/examples/affix/src/main.rs @@ -46,4 +46,4 @@ async fn main() { let acceptor = TcpListener::new("0.0.0.0:5800").bind().await; Server::new(acceptor).serve(router).await; -} \ No newline at end of file +}