chore: add lints in workspace cargo config (#223)

This commit is contained in:
Sanchith Hegde
2022-12-24 14:28:03 +05:30
committed by GitHub
parent a996f0d89b
commit e7579a4819
95 changed files with 443 additions and 383 deletions

View File

@ -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");
};

View File

@ -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() }
})

View File

@ -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()
}

View File

@ -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;