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

Add derive macro to strip enum of data #39

Merged
merged 34 commits into from
Dec 11, 2024
Merged

Add derive macro to strip enum of data #39

merged 34 commits into from
Dec 11, 2024

Conversation

jewlexx
Copy link
Owner

@jewlexx jewlexx commented Oct 19, 2023

  • Option to inherit meta from existing enum

Summary by CodeRabbit

  • New Features
    • Introduced a new procedural macro strip_enum for generating stripped enums.
    • Added new enums and functionality for converting enum variants to strings.
  • Bug Fixes
    • Deprecated certain macros with guidance for users to transition to new alternatives.
  • Chores
    • Updated development dependencies, including the addition of strum for enhanced capabilities.

@jewlexx jewlexx marked this pull request as draft December 4, 2024 01:41
Copy link

coderabbitai bot commented Dec 10, 2024

Caution

Review failed

The pull request is closed.

Walkthrough

The changes in this pull request involve modifications to the quork-proc package, including updates to the Cargo.toml file to add new development dependencies. A new procedural macro, strip_enum, is introduced in lib.rs, along with updates to existing macros for improved simplicity. The strip_enum.rs file implements the logic for the strip_enum macro, enhancing its functionality, while the test file validates the macro's behavior with various enums, including string conversion capabilities.

Changes

File Change Summary
quork-proc/Cargo.toml - Added dev-dependency: strum = { version = "0.26", features = ["derive"] }
quork-proc/src/lib.rs - Added method: pub fn strip_enum(input: TokenStream)
- Updated method signatures for several macros to use TokenStream instead of proc_macro::TokenStream
- Marked strip_lines, rstrip_lines, and lstrip_lines as deprecated with updated signatures.
quork-proc/src/strip_enum.rs - Updated function: pub fn strip_enum(ast: &mut DeriveInput) -> TokenStream to enhance processing of enum definitions and generate stripped enums.
quork-proc/tests/strip_enum.rs - Added function: pub fn enum_to_string<T: IntoEnumIterator + Display>() -> String
- Added enums: EnumWithData, EnumExclude, EnumWithInherit, EnumWithCustomIdent for testing the strip_enum functionality.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Macro
    participant Enum
    participant Output

    User->>Macro: Apply #[proc_macro_derive(Strip)]
    Macro->>Enum: Process enum definition
    Enum->>Macro: Return variants and attributes
    Macro->>Output: Generate new enum definition
    Output-->>User: Provide stripped enum
Loading

🐇 "In the code, we hop and play,
With macros brightening the way.
Stripped enums, oh so neat,
New dependencies can't be beat!
With every change, we grow and thrive,
In the world of Rust, we come alive!" 🐇


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 722cdf5 and 53cdd70.

📒 Files selected for processing (2)
  • quork-proc/Cargo.toml (1 hunks)
  • quork-proc/src/strip_enum.rs (1 hunks)

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Experiment)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@jewlexx jewlexx marked this pull request as ready for review December 10, 2024 03:04
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🧹 Outside diff range and nitpick comments (5)
quork-proc/src/strip_enum.rs (1)

143-150: Consider handling empty variant lists gracefully

If all variants are ignored, the generated enum will have no variants, which might cause issues. It's advisable to check if variants is empty and provide a helpful error message or handle it accordingly.

You can add a check before generating the output:

if variants.is_empty() {
    abort_call_site!("No variants remain after stripping. Enum cannot be empty.");
}
quork-proc/tests/strip_enum.rs (1)

13-13: Remove unused struct DummyStruct if unnecessary

The DummyStruct is defined but may not be necessary if it's not providing additional functionality.

If DummyStruct is only used as a placeholder, consider replacing it with a standard type like () or removing it if not needed.

quork-proc/src/lib.rs (3)

Line range hint 73-79: Avoid unnecessary conversion of TokenStream

In the time macro, the input is already a TokenStream, and calling .into() may be redundant.

Apply this diff:

-pub fn time(args: TokenStream, input: TokenStream) -> TokenStream {
-    let args_str = args.to_string();
-    let fmt = match args_str.as_str() {
-        "ms" | "milliseconds" => time_fn::TimeFormat::Milliseconds,
-        "ns" | "nanoseconds" => time_fn::TimeFormat::Nanoseconds,
-        _ => time_fn::TimeFormat::Seconds,
-    };
-    time_fn::attribute(fmt, &input.into()).into()
+pub fn time(args: TokenStream, input: TokenStream) -> TokenStream {
+    let args_str = args.to_string();
+    let fmt = match args_str.as_str() {
+        "ms" | "milliseconds" => time_fn::TimeFormat::Milliseconds,
+        "ns" | "nanoseconds" => time_fn::TimeFormat::Nanoseconds,
+        _ => time_fn::TimeFormat::Seconds,
+    };
+    time_fn::attribute(fmt, &input).into()
 }

Line range hint 93-105: Ensure consistency in macro functions' input and output types

Some macros use proc_macro::TokenStream while others use TokenStream. For consistency, consider unifying the types used across all macros.

Review the input and output types of all macro functions and standardize them.


Line range hint 118-125: Update deprecated functions and clarify deprecation messages

The deprecated functions rstrip_lines and lstrip_lines have deprecation messages that might be confusing. Ensure that the messages clearly guide the user to the new functions.

Apply this diff:

 #[proc_macro]
-#[deprecated = "Use rtrim_lines (renamed to avoid confusion)"]
+#[deprecated(
+    since = "0.3.2",
+    note = "Please use `rtrim_lines` instead. This function has been renamed to avoid confusion."
+)]
 pub fn rstrip_lines(input: TokenStream) -> proc_macro::TokenStream { /* ... */ }

 #[proc_macro]
-#[deprecated = "Use ltrim_lines (renamed to avoid confusion)"]
+#[deprecated(
+    since = "0.3.2",
+    note = "Please use `ltrim_lines` instead. This function has been renamed to avoid confusion."
+)]
 pub fn lstrip_lines(input: TokenStream) -> proc_macro::TokenStream { /* ... */ }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 441dd6b and 9d8a461.

📒 Files selected for processing (4)
  • quork-proc/Cargo.toml (1 hunks)
  • quork-proc/src/lib.rs (6 hunks)
  • quork-proc/src/strip_enum.rs (1 hunks)
  • quork-proc/tests/strip_enum.rs (1 hunks)
🔇 Additional comments (6)
quork-proc/Cargo.toml (1)

25-26: Confirm the usage of strum as a dev-dependency

Since strum is added as a development dependency, ensure it's only used in tests and not in the main library.

Run the following script to verify the usage:

✅ Verification successful

strum usage is correctly limited to test files

The verification confirms that strum is only used in test files (quork-proc/tests/strip_enum.rs) and is appropriately declared as a dev-dependency. There is only one other mention of strum in a TODO comment in lib.rs, which doesn't constitute actual usage.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Ensure 'strum' is only used in test files.

# Test: Search for imports of 'strum' outside the tests directory.
# Expect: No matches found outside tests/.

rg 'use\s+strum' src/ --glob '!tests/*'

Length of output: 41


Script:

#!/bin/bash
# Let's try a more comprehensive search approach

# 1. First, let's check if src/ directory exists
fd --type d "^src$"

# 2. Search for strum usage across all files (not just imports)
rg "strum" --type rust

# 3. Look specifically for test files and modules
fd -e rs "test" 

Length of output: 486

quork-proc/tests/strip_enum.rs (4)

9-11: Consider specifying return type explicitly for clarity

The enum_to_string function could be clearer if the return type is explicitly specified.

Apply this diff:

-pub fn enum_to_string<T: IntoEnumIterator + Display>() -> String {
+pub fn enum_to_string<T: IntoEnumIterator + Display>() -> String {
     T::iter().map(|v| v.to_string()).collect::<String>()
 }

(Actually, the return type is already specified, so this might be unnecessary.)


15-21: Ensure proper derivation of traits after stripping

When deriving Strip, make sure that the derived enum (EnumWithDataStripped) correctly implements the intended traits (EnumIter, Display).


40-45: Check for consistency in trait derivations

In EnumWithInherit, both Strip and Display are derived. Ensure that the stripped enum also derives the necessary traits.


48-52: Verify the correctness of the excludes_no_hook_variant test

Ensure that the test accurately reflects the expected behavior when a variant is ignored using #[stripped(ignore)].

quork-proc/src/lib.rs (1)

6-14: 🛠️ Refactor suggestion

Ensure consistent use of TokenStream imports

The code mixes proc_macro::TokenStream and TokenStream imports from proc_macro. For clarity and consistency, consider importing TokenStream explicitly and using it uniformly.

Apply this diff:

-use proc_macro::TokenStream;
+use proc_macro::TokenStream as TokenStream;

Alternatively, you can import TokenStream from proc_macro2 if appropriate.

Likely invalid or redundant comment.

}
});

list.parse_args_with(list_parser).unwrap();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Handle potential parsing errors instead of using unwrap()

Using unwrap() on list.parse_args_with(list_parser) may cause a panic if parsing fails. It's better to handle the error gracefully and provide a helpful error message to the user.

Apply this diff to handle the error:

-list.parse_args_with(list_parser).unwrap();
+if let Err(err) = list.parse_args_with(list_parser) {
+    abort!(list.span(), "Failed to parse 'stripped' attribute: {}", err);
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
list.parse_args_with(list_parser).unwrap();
if let Err(err) = list.parse_args_with(list_parser) {
abort!(list.span(), "Failed to parse 'stripped' attribute: {}", err);
}

.iter()
.filter(|attr| attr.path().is_ident("stripped_meta"))
.flat_map(|meta_attr| match &meta_attr.meta {
Meta::List(meta_data) => vec![meta_data.parse_args::<syn::Meta>().unwrap()],
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Replace unwrap() with error handling to prevent panics

Calling parse_args::<syn::Meta>().unwrap() can cause a panic if the parsing fails. It's advisable to handle the error and provide a meaningful message.

Apply this diff:

-Meta::List(meta_data) => vec![meta_data.parse_args::<syn::Meta>().unwrap()],
+Meta::List(meta_data) => {
+    match meta_data.parse_args::<syn::Meta>() {
+        Ok(meta) => vec![meta],
+        Err(err) => abort!(meta_data.span(), "Failed to parse 'stripped_meta' attribute: {}", err),
+    }
+},
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Meta::List(meta_data) => vec![meta_data.parse_args::<syn::Meta>().unwrap()],
Meta::List(meta_data) => {
match meta_data.parse_args::<syn::Meta>() {
Ok(meta) => vec![meta],
Err(err) => abort!(meta_data.span(), "Failed to parse 'stripped_meta' attribute: {}", err),
}
},

}
});

info_attr.parse_args_with(ident_parser).unwrap();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Avoid potential panics by handling parsing errors

The use of unwrap() on info_attr.parse_args_with(ident_parser) can lead to a panic if parsing fails. Consider handling the error to prevent unexpected panics and provide clearer error messages.

Apply this diff:

-info_attr.parse_args_with(ident_parser).unwrap();
+if let Err(err) = info_attr.parse_args_with(ident_parser) {
+    abort!(info_attr.span(), "Failed to parse 'ident' in 'stripped' attribute: {}", err);
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
info_attr.parse_args_with(ident_parser).unwrap();
if let Err(err) = info_attr.parse_args_with(ident_parser) {
abort!(info_attr.span(), "Failed to parse 'ident' in 'stripped' attribute: {}", err);
}

Comment on lines 96 to 124
let meta_list: Vec<syn::Meta> = attrs
.iter()
.filter(|attr| attr.path().is_ident("stripped_meta"))
.flat_map(|meta_attr| match &meta_attr.meta {
Meta::List(meta_data) => vec![meta_data.parse_args::<syn::Meta>().unwrap()],
// Meta::NameValue(MetaNameValue {
// value:
// syn::Expr::Lit(syn::ExprLit {
// lit: syn::Lit::Str(path),
// ..
// }),
// ..
// }) => {
// if &path.value() == "inherit" {
// attrs
// .iter()
// .filter(|attr| !attr.path().is_ident("stripped_meta"))
// .map(|attr| attr.meta.clone())
// .collect()
// } else {
// abort!(path.span(), "Expected `inherit`");
// }
// }
_ => abort!(
meta_attr.span(),
"Expected #[stripped_meta(...)]. Found other style attribute."
),
})
.collect();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve parsing of stripped_meta attributes and error handling

The current implementation may not handle multiple #[stripped_meta(...)] attributes correctly and uses unwrap() which can panic. Consider parsing all attributes properly and handling errors.

Here's a suggested change:

-let meta_list: Vec<syn::Meta> = attrs
-    .iter()
-    .filter(|attr| attr.path().is_ident("stripped_meta"))
-    .flat_map(|meta_attr| match &meta_attr.meta {
-        Meta::List(meta_data) => vec![meta_data.parse_args::<syn::Meta>().unwrap()],
-        _ => abort!(
-            meta_attr.span(),
-            "Expected #[stripped_meta(...)]. Found other style attribute."
-        ),
-    })
-    .collect();
+let mut meta_list: Vec<syn::Meta> = Vec::new();
+for attr in attrs.iter().filter(|attr| attr.path().is_ident("stripped_meta")) {
+    match attr.parse_meta() {
+        Ok(Meta::List(meta_data)) => {
+            for nested_meta in meta_data.nested.iter() {
+                if let syn::NestedMeta::Meta(meta) = nested_meta {
+                    meta_list.push(meta.clone());
+                } else {
+                    abort!(
+                        nested_meta.span(),
+                        "Invalid format in 'stripped_meta' attribute."
+                    );
+                }
+            }
+        }
+        _ => abort!(
+            attr.span(),
+            "Expected #[stripped_meta(...)] with meta list."
+        ),
+    }
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let meta_list: Vec<syn::Meta> = attrs
.iter()
.filter(|attr| attr.path().is_ident("stripped_meta"))
.flat_map(|meta_attr| match &meta_attr.meta {
Meta::List(meta_data) => vec![meta_data.parse_args::<syn::Meta>().unwrap()],
// Meta::NameValue(MetaNameValue {
// value:
// syn::Expr::Lit(syn::ExprLit {
// lit: syn::Lit::Str(path),
// ..
// }),
// ..
// }) => {
// if &path.value() == "inherit" {
// attrs
// .iter()
// .filter(|attr| !attr.path().is_ident("stripped_meta"))
// .map(|attr| attr.meta.clone())
// .collect()
// } else {
// abort!(path.span(), "Expected `inherit`");
// }
// }
_ => abort!(
meta_attr.span(),
"Expected #[stripped_meta(...)]. Found other style attribute."
),
})
.collect();
let mut meta_list: Vec<syn::Meta> = Vec::new();
for attr in attrs.iter().filter(|attr| attr.path().is_ident("stripped_meta")) {
match attr.parse_meta() {
Ok(Meta::List(meta_data)) => {
for nested_meta in meta_data.nested.iter() {
if let syn::NestedMeta::Meta(meta) = nested_meta {
meta_list.push(meta.clone());
} else {
abort!(
nested_meta.span(),
"Invalid format in 'stripped_meta' attribute."
);
}
}
}
_ => abort!(
attr.span(),
"Expected #[stripped_meta(...)] with meta list."
),
}
}

Comment on lines 7 to 28
variant.attrs.iter().any(|attr| match attr.meta {
syn::Meta::List(ref list) if list.path.is_ident("stripped") => {
let mut ignored = false;

let list_parser = syn::meta::parser(|meta| {
if meta.path.is_ident("ignore") {
ignored = true;
Ok(())
} else {
Err(meta.error("unsupported stripped property"))
}
});

list.parse_args_with(list_parser).unwrap();

ignored
}
_ => abort!(
attr.span(),
"Expected list-style (i.e #[stripped(...)]), found other style attribute macro"
),
})
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Ensure correct matching of attributes to avoid unexpected behavior

The pattern matching in the ignore_variant function may incorrectly handle attributes that are not #[stripped(...)], potentially causing unintended aborts. Ensure that only the relevant attributes are processed and others are ignored gracefully.

Consider refining the match statement to handle only the #[stripped(...)] attributes and skip others without aborting. Here's a suggested change:

-fn ignore_variant(variant: &Variant) -> bool {
-    variant.attrs.iter().any(|attr| match attr.meta {
-        syn::Meta::List(ref list) if list.path.is_ident("stripped") => {
-            // Existing code...
-        }
-        _ => abort!(
-            attr.span(),
-            "Expected list-style (i.e #[stripped(...)]), found other style attribute macro"
-        ),
-    })
+fn ignore_variant(variant: &Variant) -> bool {
+    variant.attrs.iter().any(|attr| {
+        if attr.path().is_ident("stripped") {
+            match attr.parse_meta() {
+                Ok(syn::Meta::List(list)) => {
+                    // Existing code...
+                    let mut ignored = false;
+                    let list_parser = syn::meta::parser(|meta| {
+                        if meta.path.is_ident("ignore") {
+                            ignored = true;
+                            Ok(())
+                        } else {
+                            Err(meta.error("unsupported stripped property"))
+                        }
+                    });
+                    if let Err(err) = list.parse_args_with(list_parser) {
+                        abort!(list.span(), "Failed to parse 'stripped' attribute: {}", err);
+                    }
+                    ignored
+                }
+                _ => abort!(
+                    attr.span(),
+                    "Expected list-style (i.e #[stripped(...)]), found other style attribute."
+                ),
+            }
+        } else {
+            false
+        }
+    })
 }

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines 72 to 94
let new_ident = if let Some(info_attr_pos) = attrs
.iter()
.position(|attr| attr.path().is_ident("stripped"))
{
let info_attr = attrs.remove(info_attr_pos);

let mut new_ident: Option<Ident> = None;

let ident_parser = syn::meta::parser(|meta| {
if meta.path.is_ident("ident") {
new_ident = Some(meta.value()?.parse()?);
Ok(())
} else {
Err(meta.error("unsupported stripped property"))
}
});

info_attr.parse_args_with(ident_parser).unwrap();

new_ident.unwrap_or_else(default_ident)
} else {
default_ident()
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consistent attribute parsing and error handling

In the strip_enum function, the parsing of the #[stripped] attribute should handle errors gracefully and consistently, similar to the previous suggestions.

Apply this diff:

-let new_ident = if let Some(info_attr_pos) = attrs
-    .iter()
-    .position(|attr| attr.path().is_ident("stripped"))
-{
-    let info_attr = attrs.remove(info_attr_pos);
-
-    let mut new_ident: Option<Ident> = None;
-
-    let ident_parser = syn::meta::parser(|meta| {
-        if meta.path.is_ident("ident") {
-            new_ident = Some(meta.value()?.parse()?);
-            Ok(())
-        } else {
-            Err(meta.error("unsupported stripped property"))
-        }
-    });
-
-    info_attr.parse_args_with(ident_parser).unwrap();
-
-    new_ident.unwrap_or_else(default_ident)
-} else {
-    default_ident()
-};
+let new_ident = if let Some(info_attr_pos) = attrs
+    .iter()
+    .position(|attr| attr.path().is_ident("stripped"))
+{
+    let info_attr = attrs.remove(info_attr_pos);
+
+    let mut new_ident: Option<Ident> = None;
+
+    let ident_parser = syn::meta::parser(|meta| {
+        if meta.path.is_ident("ident") {
+            new_ident = Some(meta.value()?.parse()?);
+            Ok(())
+        } else {
+            Err(meta.error("unsupported stripped property"))
+        }
+    });
+
+    if let Err(err) = info_attr.parse_args_with(ident_parser) {
+        abort!(info_attr.span(), "Failed to parse 'stripped' attribute: {}", err);
+    }
+
+    new_ident.unwrap_or_else(default_ident)
+} else {
+    default_ident()
+};
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let new_ident = if let Some(info_attr_pos) = attrs
.iter()
.position(|attr| attr.path().is_ident("stripped"))
{
let info_attr = attrs.remove(info_attr_pos);
let mut new_ident: Option<Ident> = None;
let ident_parser = syn::meta::parser(|meta| {
if meta.path.is_ident("ident") {
new_ident = Some(meta.value()?.parse()?);
Ok(())
} else {
Err(meta.error("unsupported stripped property"))
}
});
info_attr.parse_args_with(ident_parser).unwrap();
new_ident.unwrap_or_else(default_ident)
} else {
default_ident()
};
let new_ident = if let Some(info_attr_pos) = attrs
.iter()
.position(|attr| attr.path().is_ident("stripped"))
{
let info_attr = attrs.remove(info_attr_pos);
let mut new_ident: Option<Ident> = None;
let ident_parser = syn::meta::parser(|meta| {
if meta.path.is_ident("ident") {
new_ident = Some(meta.value()?.parse()?);
Ok(())
} else {
Err(meta.error("unsupported stripped property"))
}
});
if let Err(err) = info_attr.parse_args_with(ident_parser) {
abort!(info_attr.span(), "Failed to parse 'stripped' attribute: {}", err);
}
new_ident.unwrap_or_else(default_ident)
} else {
default_ident()
};

quork-proc/Cargo.toml Outdated Show resolved Hide resolved
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Outside diff range and nitpick comments (3)
quork-proc/tests/strip_enum.rs (1)

15-28: Consider adding edge cases to the test suite.

While the basic functionality is well-tested, consider adding test cases for:

  • Empty enums
  • Single variant enums
  • Enums with complex data types
quork-proc/src/strip_enum.rs (2)

6-35: Consider more graceful handling of non-stripped attributes.

The function currently aborts on any non-#[stripped(...)] attribute, which might be too strict. Consider ignoring non-stripped attributes instead of aborting, as variants might have other valid attributes.

-        _ => abort!(
-            attr.span(),
-            "Expected list-style (i.e #[stripped(...)]), found other style attribute macro"
-        ),
+        _ => false,

44-52: Remove or document commented code.

The commented-out MetaArgs struct and its implementation should either be:

  1. Removed if no longer needed
  2. Implemented if required for inheritance functionality
  3. Documented with a TODO comment if planned for future use
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 9d8a461 and 722cdf5.

📒 Files selected for processing (2)
  • quork-proc/src/strip_enum.rs (1 hunks)
  • quork-proc/tests/strip_enum.rs (1 hunks)
🔇 Additional comments (4)
quork-proc/tests/strip_enum.rs (2)

1-11: LGTM! Well-designed helper function.

The helper function makes good use of trait bounds to ensure type safety and provides a clean way to test enum variants.


30-60: LGTM! Good test coverage for ignore functionality.

The test effectively verifies that variants marked with #[stripped(ignore)] are excluded from the stripped enum.

quork-proc/src/strip_enum.rs (2)

166-171: LGTM! Clean token stream generation.

The quote macro usage is clean and correct, with proper interpolation and repetition syntax.


54-156: ⚠️ Potential issue

Good error handling improvements, but inheritance needs attention.

The error handling has been improved with helpful messages, but the inheritance functionality (lines 122-139) is commented out. This should be either:

  1. Implemented to support the test case in strip_enum.rs
  2. Removed along with related test cases
✅ Verification successful

Let me check for any test cases or documentation related to inheritance functionality.


Let me check the test directory structure and content more broadly to ensure we're not missing anything.


Remove commented-out inheritance code as it's not being used

The inheritance functionality is commented out in the implementation and there are no test cases or documentation that rely on the inherit feature. The test file strip_enum.rs only shows usage of stripped_meta for derive and strum attributes, but no inheritance-related test cases. The commented-out code can be safely removed to maintain cleaner codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for any usage of inheritance in tests or documentation
rg -A 5 "inherit" .

Length of output: 1025


Script:

#!/bin/bash
# Search for test cases related to inheritance
rg -l "stripped_meta.*inherit" quork-proc/tests/
# Check for any documentation mentioning inheritance
rg -l "inherit" quork-proc/README.md quork-proc/docs/ 2>/dev/null
# Look for test files related to strip_enum
fd "strip.*test" quork-proc/tests/

Length of output: 141


Script:

#!/bin/bash
# List all files in the tests directory
fd . quork-proc/tests/
# Check content of test files for any stripped_meta usage
rg -A 5 "stripped_meta" quork-proc/tests/

Length of output: 1795

Comment on lines +40 to +46
#[derive(Strip)]
#[stripped_meta(derive(EnumIter))]
#[stripped_meta(strum(serialize_all = "kebab-case"))]
enum EnumWithInherit {
Test1(DummyStruct),
}

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Inheritance functionality is commented out and needs implementation

Based on the code inspection:

  • The inheritance implementation is commented out in strip_enum.rs (visible in the commented block containing inherit logic)
  • There's a test case EnumWithInherit expecting this functionality
  • No alternative or active implementation of inheritance was found

This confirms the original review comment's observation. The feature is incomplete as the implementation is commented out while the test exists.

🔗 Analysis chain

Verify inheritance functionality implementation.

The test case exists for enum inheritance, but the corresponding implementation appears to be commented out in strip_enum.rs (lines 122-139). Either implement the inheritance functionality or remove the test case.


Let me check the implementation details in the strip_enum.rs file.


Let me check if there are any active implementations or tests related to inheritance functionality.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if there are any other tests or implementations of inheritance
rg -l "inherit" .

Length of output: 48


Script:

#!/bin/bash
# Check the implementation in strip_enum.rs
rg -A 5 -B 5 "inherit" ./quork-proc/src/strip_enum.rs

Length of output: 915


Script:

#!/bin/bash
# Search for stripped_meta and inheritance related patterns in tests
rg -A 5 "stripped_meta" ./quork-proc/tests/strip_enum.rs

Length of output: 780

@jewlexx jewlexx merged commit 829a5e9 into trunk Dec 11, 2024
4 of 5 checks passed
@jewlexx jewlexx deleted the strip-enum branch December 11, 2024 00:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant