-
Notifications
You must be signed in to change notification settings - Fork 2
Allow transforms in substruct fields #7
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
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR introduces field type transformations to the substruct macro, allowing substruct fields to have different types than their parent fields through fallible conversions. The main feature enables transforming Option<T> to T via unwrap or converting between types using TryInto.
Key changes:
- Added
unwraptransform to convertOption<T>fields toTin substructs - Added
try_intotransform to convert field types usingTryInto<U> - Generated
TryFromimplementations instead ofFromwhen transforms are used - Created conversion error types for handling transformation failures
Reviewed Changes
Copilot reviewed 16 out of 17 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| src/expr.rs | Extended expression parser to handle transform syntax like Name(unwrap) and Name(try_into = Type) |
| src/substruct.rs | Added transform logic, field configuration tracking, and TryFrom implementation generation |
| src/lib.rs | Updated documentation with transformation examples and usage patterns |
| tests/it.rs | Added comprehensive tests for unwrap, try_into, and mixed transformation scenarios |
| tests/ui/pass/*.rs | Added UI test cases covering various transformation combinations and edge cases |
| tests/ui/fail/*.rs | Added error test cases for invalid transform syntax |
| README.md | Enhanced documentation with transformation examples and usage guide |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| let a = b.into_a(5); | ||
|
|
||
| assert!(matches!(a, A(5, 32))) | ||
| assert!(matches!(a, A(5, 32))); |
Copilot
AI
Sep 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing semicolon in assert! macro call. This was fixed from the previous version.
| if !attr.path().is_ident("doc") { | ||
| return Err(syn::Error::new_spanned( | ||
| &attr, | ||
| attr, |
Copilot
AI
Sep 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed unnecessary reference operator (&) when the argument is already a reference. This improves code clarity.
|
|
||
| for error in self.errors.drain(..) { | ||
| self.tokens.extend(error.into_compile_error()) | ||
| self.tokens.extend(error.into_compile_error()); |
Copilot
AI
Sep 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing semicolon added to complete the statement properly.
| }, | ||
| syn::Data::Union(data) => self.filter_fields_named(&mut data.fields, name), | ||
| }; | ||
| } |
Copilot
AI
Sep 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replaced semicolon with closing brace to properly close the match expression.
| .keys() | ||
| .cloned() | ||
| .map(|key| key.into_ident()) | ||
| .map(IdentOrIndex::into_ident) |
Copilot
AI
Sep 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Simplified closure to method reference for better readability and performance.
|
|
||
| if args.len() > 5 { | ||
| attrs.push(syn::parse_quote!(#[allow(clippy::too_many_arguments)])) | ||
| attrs.push(syn::parse_quote!(#[allow(clippy::too_many_arguments)])); |
Copilot
AI
Sep 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing semicolon added to complete the statement.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Hi there, first of all thanks for the crate.
Sometimes it's useful to have a substruct have a different field than (but fallibly convertible to) the parent one, such as
Option<T>->T, orT: TryInto<U>->U.This PR enables that by introducing transforms:
unwrapandtry_into. When present, the crate generates aTryFromimplementation instead ofFromand an associated error type.