mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-29 00:49:42 +08:00
chore: add lints in workspace cargo config (#223)
This commit is contained in:
@ -133,6 +133,11 @@ pub fn diesel_enum(
|
||||
/// ```
|
||||
///
|
||||
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if a struct without named fields is provided as input to the macro
|
||||
// FIXME: Remove allowed warnings, raise compile errors in a better manner instead of panicking
|
||||
#[allow(clippy::panic, clippy::unwrap_used)]
|
||||
#[proc_macro_derive(Setter, attributes(auth_based))]
|
||||
pub fn setter(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
let input = syn::parse_macro_input!(input as syn::DeriveInput);
|
||||
@ -145,6 +150,7 @@ pub fn setter(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
{
|
||||
named
|
||||
} else {
|
||||
// FIXME: Use `compile_error!()` instead
|
||||
panic!("You can't use this proc-macro on structs without fields");
|
||||
};
|
||||
|
||||
|
||||
@ -74,11 +74,15 @@ fn implement_error_type(
|
||||
Fields::Unnamed(..) => quote! { (..) },
|
||||
Fields::Named(..) => quote! { {..} },
|
||||
};
|
||||
// Safety: Missing attributes are already checked before this function is called.
|
||||
#[allow(clippy::unwrap_used)]
|
||||
let error_type = properties.error_type.as_ref().unwrap();
|
||||
|
||||
arms.push(quote! { #enum_name::#ident #params => #error_type });
|
||||
}
|
||||
|
||||
// Safety: Missing attributes are already checked before this function is called.
|
||||
#[allow(clippy::unwrap_used)]
|
||||
let error_type_enum = type_properties.error_type_enum.as_ref().unwrap();
|
||||
quote! {
|
||||
pub fn error_type(&self) -> #error_type_enum {
|
||||
@ -101,6 +105,8 @@ fn implement_error_code(
|
||||
Fields::Unnamed(..) => quote! { (..) },
|
||||
Fields::Named(..) => quote! { {..} },
|
||||
};
|
||||
// Safety: Missing attributes are already checked before this function is called.
|
||||
#[allow(clippy::unwrap_used)]
|
||||
let error_code = properties.code.as_ref().unwrap();
|
||||
|
||||
arms.push(quote! { #enum_name::#ident #params => #error_code.to_string() });
|
||||
@ -129,11 +135,17 @@ fn implement_error_message(
|
||||
let fields = fields
|
||||
.named
|
||||
.iter()
|
||||
.map(|f| f.ident.as_ref().unwrap())
|
||||
.map(|f| {
|
||||
// Safety: Named fields are guaranteed to have an identifier.
|
||||
#[allow(clippy::unwrap_used)]
|
||||
f.ident.as_ref().unwrap()
|
||||
})
|
||||
.collect::<Punctuated<&Ident, Comma>>();
|
||||
quote! { {#fields} }
|
||||
}
|
||||
};
|
||||
// Safety: Missing attributes are already checked before this function is called.
|
||||
#[allow(clippy::unwrap_used)]
|
||||
let error_message = properties.message.as_ref().unwrap();
|
||||
|
||||
arms.push(quote! { #enum_name::#ident #params => format!(#error_message) });
|
||||
@ -150,7 +162,7 @@ fn implement_error_message(
|
||||
|
||||
fn implement_serialize(
|
||||
enum_name: &Ident,
|
||||
generics: (&ImplGenerics, &TypeGenerics, Option<&WhereClause>),
|
||||
generics: (&ImplGenerics<'_>, &TypeGenerics<'_>, Option<&WhereClause>),
|
||||
type_properties: &ErrorTypeProperties,
|
||||
variants_properties_map: &HashMap<&Variant, ErrorVariantProperties>,
|
||||
) -> TokenStream {
|
||||
@ -165,14 +177,22 @@ fn implement_serialize(
|
||||
let fields = fields
|
||||
.named
|
||||
.iter()
|
||||
.map(|f| f.ident.as_ref().unwrap())
|
||||
.map(|f| {
|
||||
// Safety: Named fields are guaranteed to have an identifier.
|
||||
#[allow(clippy::unwrap_used)]
|
||||
f.ident.as_ref().unwrap()
|
||||
})
|
||||
.collect::<Punctuated<&Ident, Comma>>();
|
||||
quote! { {#fields} }
|
||||
}
|
||||
};
|
||||
// Safety: Missing attributes are already checked before this function is called.
|
||||
#[allow(clippy::unwrap_used)]
|
||||
let error_message = properties.message.as_ref().unwrap();
|
||||
let msg_unused_fields = get_unused_fields(&variant.fields, &error_message.value()).unwrap();
|
||||
let msg_unused_fields = get_unused_fields(&variant.fields, &error_message.value());
|
||||
|
||||
// Safety: Missing attributes are already checked before this function is called.
|
||||
#[allow(clippy::unwrap_used)]
|
||||
let error_type_enum = type_properties.error_type_enum.as_ref().unwrap();
|
||||
let response_definition = if msg_unused_fields.is_empty() {
|
||||
quote! {
|
||||
@ -188,6 +208,8 @@ fn implement_serialize(
|
||||
let mut extra_fields = Vec::new();
|
||||
for field in &msg_unused_fields {
|
||||
let vis = &field.vis;
|
||||
// Safety: `msq_unused_fields` is expected to contain named fields only.
|
||||
#[allow(clippy::unwrap_used)]
|
||||
let ident = &field.ident.as_ref().unwrap();
|
||||
let ty = &field.ty;
|
||||
extra_fields.push(quote! { #vis #ident: #ty });
|
||||
@ -204,12 +226,20 @@ fn implement_serialize(
|
||||
}
|
||||
};
|
||||
|
||||
// Safety: Missing attributes are already checked before this function is called.
|
||||
#[allow(clippy::unwrap_used)]
|
||||
let error_type = properties.error_type.as_ref().unwrap();
|
||||
// Safety: Missing attributes are already checked before this function is called.
|
||||
#[allow(clippy::unwrap_used)]
|
||||
let code = properties.code.as_ref().unwrap();
|
||||
// Safety: Missing attributes are already checked before this function is called.
|
||||
#[allow(clippy::unwrap_used)]
|
||||
let message = properties.message.as_ref().unwrap();
|
||||
let extra_fields = msg_unused_fields
|
||||
.iter()
|
||||
.map(|field| {
|
||||
// Safety: `extra_fields` is expected to contain named fields only.
|
||||
#[allow(clippy::unwrap_used)]
|
||||
let field_name = field.ident.as_ref().unwrap();
|
||||
quote! { #field_name: #field_name.to_owned() }
|
||||
})
|
||||
|
||||
@ -24,13 +24,13 @@ enum EnumMeta {
|
||||
}
|
||||
|
||||
impl Parse for EnumMeta {
|
||||
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
|
||||
fn parse(input: syn::parse::ParseStream<'_>) -> syn::Result<Self> {
|
||||
let lookahead = input.lookahead1();
|
||||
if lookahead.peek(keyword::error_type_enum) {
|
||||
let keyword = input.parse()?;
|
||||
input.parse::<Token![=]>()?;
|
||||
let value = input.parse()?;
|
||||
Ok(EnumMeta::ErrorTypeEnum { keyword, value })
|
||||
Ok(Self::ErrorTypeEnum { keyword, value })
|
||||
} else {
|
||||
Err(lookahead.error())
|
||||
}
|
||||
@ -40,7 +40,7 @@ impl Parse for EnumMeta {
|
||||
impl Spanned for EnumMeta {
|
||||
fn span(&self) -> proc_macro2::Span {
|
||||
match self {
|
||||
EnumMeta::ErrorTypeEnum { keyword, .. } => keyword.span(),
|
||||
Self::ErrorTypeEnum { keyword, .. } => keyword.span(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -83,6 +83,13 @@ impl HasErrorTypeProperties for DeriveInput {
|
||||
}
|
||||
}
|
||||
|
||||
if output.error_type_enum.is_none() {
|
||||
return Err(syn::Error::new(
|
||||
self.span(),
|
||||
"error(error_type_enum) attribute not found",
|
||||
));
|
||||
}
|
||||
|
||||
Ok(output)
|
||||
}
|
||||
}
|
||||
@ -103,23 +110,23 @@ enum VariantMeta {
|
||||
}
|
||||
|
||||
impl Parse for VariantMeta {
|
||||
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
|
||||
fn parse(input: syn::parse::ParseStream<'_>) -> syn::Result<Self> {
|
||||
let lookahead = input.lookahead1();
|
||||
if lookahead.peek(keyword::error_type) {
|
||||
let keyword = input.parse()?;
|
||||
let _: Token![=] = input.parse()?;
|
||||
let value = input.parse()?;
|
||||
Ok(VariantMeta::ErrorType { keyword, value })
|
||||
Ok(Self::ErrorType { keyword, value })
|
||||
} else if lookahead.peek(keyword::code) {
|
||||
let keyword = input.parse()?;
|
||||
let _: Token![=] = input.parse()?;
|
||||
let value = input.parse()?;
|
||||
Ok(VariantMeta::Code { keyword, value })
|
||||
Ok(Self::Code { keyword, value })
|
||||
} else if lookahead.peek(keyword::message) {
|
||||
let keyword = input.parse()?;
|
||||
let _: Token![=] = input.parse()?;
|
||||
let value = input.parse()?;
|
||||
Ok(VariantMeta::Message { keyword, value })
|
||||
Ok(Self::Message { keyword, value })
|
||||
} else {
|
||||
Err(lookahead.error())
|
||||
}
|
||||
@ -129,9 +136,9 @@ impl Parse for VariantMeta {
|
||||
impl Spanned for VariantMeta {
|
||||
fn span(&self) -> proc_macro2::Span {
|
||||
match self {
|
||||
VariantMeta::ErrorType { keyword, .. } => keyword.span,
|
||||
VariantMeta::Code { keyword, .. } => keyword.span,
|
||||
VariantMeta::Message { keyword, .. } => keyword.span,
|
||||
Self::ErrorType { keyword, .. } => keyword.span,
|
||||
Self::Code { keyword, .. } => keyword.span,
|
||||
Self::Message { keyword, .. } => keyword.span,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -220,19 +227,21 @@ pub(super) fn check_missing_attributes(
|
||||
}
|
||||
|
||||
/// Get all the fields not used in the error message.
|
||||
pub(super) fn get_unused_fields(fields: &Fields, message: &str) -> syn::Result<Vec<Field>> {
|
||||
pub(super) fn get_unused_fields(fields: &Fields, message: &str) -> Vec<Field> {
|
||||
let fields = match fields {
|
||||
syn::Fields::Unit => Vec::new(),
|
||||
syn::Fields::Unnamed(_) => Vec::new(),
|
||||
syn::Fields::Named(fields) => fields.named.iter().cloned().collect(),
|
||||
};
|
||||
|
||||
Ok(fields
|
||||
fields
|
||||
.iter()
|
||||
.filter(|&field| {
|
||||
// Safety: Named fields are guaranteed to have an identifier.
|
||||
#[allow(clippy::unwrap_used)]
|
||||
let field_name = format!("{}", field.ident.as_ref().unwrap());
|
||||
!message.contains(&field_name)
|
||||
})
|
||||
.cloned()
|
||||
.collect())
|
||||
.collect()
|
||||
}
|
||||
|
||||
@ -83,7 +83,7 @@ enum Conversion {
|
||||
}
|
||||
|
||||
impl From<String> for Conversion {
|
||||
fn from(s: String) -> Conversion {
|
||||
fn from(s: String) -> Self {
|
||||
match s.as_str() {
|
||||
"validate_request" => Self::ValidateRequest,
|
||||
"get_tracker" => Self::GetTracker,
|
||||
@ -91,6 +91,7 @@ impl From<String> for Conversion {
|
||||
"update_tracker" => Self::UpdateTracker,
|
||||
"post_tracker" => Self::PostUpdateTracker,
|
||||
"all" => Self::All,
|
||||
#[allow(clippy::panic)] // FIXME: Use `compile_error!()` instead
|
||||
_ => panic!("Invalid conversion identifier {}", s),
|
||||
}
|
||||
}
|
||||
@ -118,36 +119,36 @@ impl Conversion {
|
||||
fn to_function(&self, ident: Derives) -> TokenStream {
|
||||
let req_type = Self::get_req_type(ident);
|
||||
match self {
|
||||
Conversion::ValidateRequest => quote! {
|
||||
Self::ValidateRequest => quote! {
|
||||
fn to_validate_request(&self) -> RouterResult<&(dyn ValidateRequest<F,#req_type> + Send + Sync)> {
|
||||
Ok(self)
|
||||
}
|
||||
},
|
||||
Conversion::GetTracker => quote! {
|
||||
Self::GetTracker => quote! {
|
||||
fn to_get_tracker(&self) -> RouterResult<&(dyn GetTracker<F,PaymentData<F>,#req_type> + Send + Sync)> {
|
||||
Ok(self)
|
||||
}
|
||||
},
|
||||
Conversion::Domain => quote! {
|
||||
Self::Domain => quote! {
|
||||
fn to_domain(&self) -> RouterResult<&dyn Domain<F,#req_type>> {
|
||||
Ok(self)
|
||||
}
|
||||
},
|
||||
Conversion::UpdateTracker => quote! {
|
||||
Self::UpdateTracker => quote! {
|
||||
fn to_update_tracker(&self) -> RouterResult<&(dyn UpdateTracker<F,PaymentData<F>,#req_type> + Send + Sync)> {
|
||||
Ok(self)
|
||||
}
|
||||
},
|
||||
Conversion::PostUpdateTracker => quote! {
|
||||
Self::PostUpdateTracker => quote! {
|
||||
fn to_post_update_tracker(&self) -> RouterResult<&(dyn PostUpdateTracker<F, PaymentData<F>, #req_type> + Send + Sync)> {
|
||||
Ok(self)
|
||||
}
|
||||
},
|
||||
Conversion::All => {
|
||||
let validate_request = Conversion::ValidateRequest.to_function(ident);
|
||||
let get_tracker = Conversion::GetTracker.to_function(ident);
|
||||
let domain = Conversion::Domain.to_function(ident);
|
||||
let update_tracker = Conversion::UpdateTracker.to_function(ident);
|
||||
Self::All => {
|
||||
let validate_request = Self::ValidateRequest.to_function(ident);
|
||||
let get_tracker = Self::GetTracker.to_function(ident);
|
||||
let domain = Self::Domain.to_function(ident);
|
||||
let update_tracker = Self::UpdateTracker.to_function(ident);
|
||||
|
||||
quote! {
|
||||
#validate_request
|
||||
@ -162,36 +163,36 @@ impl Conversion {
|
||||
fn to_ref_function(&self, ident: Derives) -> TokenStream {
|
||||
let req_type = Self::get_req_type(ident);
|
||||
match self {
|
||||
Conversion::ValidateRequest => quote! {
|
||||
Self::ValidateRequest => quote! {
|
||||
fn to_validate_request(&self) -> RouterResult<&(dyn ValidateRequest<F,#req_type> + Send + Sync)> {
|
||||
Ok(*self)
|
||||
}
|
||||
},
|
||||
Conversion::GetTracker => quote! {
|
||||
Self::GetTracker => quote! {
|
||||
fn to_get_tracker(&self) -> RouterResult<&(dyn GetTracker<F,PaymentData<F>,#req_type> + Send + Sync)> {
|
||||
Ok(*self)
|
||||
}
|
||||
},
|
||||
Conversion::Domain => quote! {
|
||||
Self::Domain => quote! {
|
||||
fn to_domain(&self) -> RouterResult<&(dyn Domain<F,#req_type>)> {
|
||||
Ok(*self)
|
||||
}
|
||||
},
|
||||
Conversion::UpdateTracker => quote! {
|
||||
Self::UpdateTracker => quote! {
|
||||
fn to_update_tracker(&self) -> RouterResult<&(dyn UpdateTracker<F,PaymentData<F>,#req_type> + Send + Sync)> {
|
||||
Ok(*self)
|
||||
}
|
||||
},
|
||||
Conversion::PostUpdateTracker => quote! {
|
||||
Self::PostUpdateTracker => quote! {
|
||||
fn to_post_update_tracker(&self) -> RouterResult<&(dyn PostUpdateTracker<F, PaymentData<F>, #req_type> + Send + Sync)> {
|
||||
Ok(*self)
|
||||
}
|
||||
},
|
||||
Conversion::All => {
|
||||
let validate_request = Conversion::ValidateRequest.to_ref_function(ident);
|
||||
let get_tracker = Conversion::GetTracker.to_ref_function(ident);
|
||||
let domain = Conversion::Domain.to_ref_function(ident);
|
||||
let update_tracker = Conversion::UpdateTracker.to_ref_function(ident);
|
||||
Self::All => {
|
||||
let validate_request = Self::ValidateRequest.to_ref_function(ident);
|
||||
let get_tracker = Self::GetTracker.to_ref_function(ident);
|
||||
let domain = Self::Domain.to_ref_function(ident);
|
||||
let update_tracker = Self::UpdateTracker.to_ref_function(ident);
|
||||
|
||||
quote! {
|
||||
#validate_request
|
||||
@ -205,6 +206,7 @@ impl Conversion {
|
||||
}
|
||||
|
||||
fn find_operation_attr(a: &[syn::Attribute]) -> syn::Attribute {
|
||||
#[allow(clippy::expect_used)] // FIXME: Use `compile_error!()` instead
|
||||
a.iter()
|
||||
.find(|a| {
|
||||
a.path
|
||||
@ -232,6 +234,9 @@ fn find_value(v: NestedMeta) -> Option<(String, Vec<String>)> {
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Propagate errors in a better manner instead of `expect()`, maybe use `compile_error!()`
|
||||
#[allow(clippy::unwrap_used, clippy::expect_used)]
|
||||
fn find_properties(attr: &syn::Attribute) -> Option<HashMap<String, Vec<String>>> {
|
||||
let meta = attr.parse_meta();
|
||||
match meta {
|
||||
@ -251,6 +256,8 @@ fn find_properties(attr: &syn::Attribute) -> Option<HashMap<String, Vec<String>>
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Propagate errors in a better manner instead of `expect()`, maybe use `compile_error!()`
|
||||
#[allow(clippy::expect_used)]
|
||||
pub fn operation_derive_inner(token: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
let input = parse_macro_input!(token as DeriveInput);
|
||||
let struct_name = &input.ident;
|
||||
|
||||
Reference in New Issue
Block a user